요 카테고리가 적절한 지는 잘모르겠네요.
부적절하다면 옮겨주시길… (_ _)
storage 에 데이터를 인덱싱하는 메서드를 만들고 있는데요.
일단 아래와 같은 메서드가 있슴다.
public async Task<(int page, int total)> IndexAsync(int starting, CancellationToken cancellationToken)
{
var start = starting;
var totalCount = 0;
var items = await client.GetAsync(starting, cancellationToken);
if (items.Any() is false)
{
return (0, 0);
}
var contexts = items.OfType<Context>().ToList();
await client.IndexAsync(contexts, cancellationToken);
totalCount += await client.CountAsync();
return (start, totalCount);
}
public (int page, int total) Index(int starting)
{
var start = starting;
var totalCount = 0;
var items = client.Get(starting);
if (items.Any() is false)
{
return (0, 0);
}
var contexts = items.OfType<Context>().ToList();
client.Index(contexts);
totalCount += client.Count();
return (start, totalCount);
}
당연히 의사코드입니다. (실행 ㄴㄴ)
데이터를 storage 에 Index 하는 기능을 동기/비동기 모두 지원하기 위해 작성 중인 메서드인데
요거 중간에 client
호출부를 제외한 나머지 로직이 Index / IndexAsync
요 두 메서드 간 완전히 동일합니다.
근데 요걸 중복되는 내용을 정리해서 깔끔하게 리팩토링하고 싶은데
잘 안 되네요…-ㅁ-
혹시 아이디어나 팁이 있으시면 도움 좀 부탁드려요… (_ _)
2개의 좋아요
살짝 코파일럿의 도움을 받아
private (int page, int total) IndexCore(int starting,
Func<int, IEnumerable<object>> getItems,
Action<List<Context>> indexItems,
Func<int> countItems)
{
var start = starting;
var totalCount = 0;
var items = getItems(starting);
if (items.Any() is false)
{
return (0, 0);
}
var contexts = items.OfType<Context>().ToList();
indexItems(contexts);
totalCount += countItems();
return (start, totalCount);
}
public async Task<(int page, int total)> IndexAsync(int starting,
CancellationToken cancellationToken)
{
return await Task.Run(() => IndexCore(starting,
start => client.GetAsync(start, cancellationToken).Result,
contexts => client.IndexAsync(contexts, cancellationToken).Wait(),
() => context.CountAsync().Result), cancellationToken);
}
public (int page, int total) Index(int starting)
{
return IndexCore(starting,
start => client.Get(start),
contexts => client.Index(contexts),
() => context.Count());
}
1개의 좋아요
처음 이거 비슷하게 생각하고 코드를 찌끄려봤는데
비동기 호출 구간에서 Result 나 Wait 을 이용해 블럭을 거는 건 오히려 손해인지라
생각보다 깔끔하게 뭔가 분리는 어려운 거 같네요.
게다가 중간에 삽입되는 비동기 호출 로직이 많아지면, 비동기 호출마다 델리게이트로 인자를 받아야하는 게 약간… 불합리한 느낌적인 느낌?
쉽지 않군요.,… =ㅅ=;;;
비동기 코드는 처음부터 끝까지 비동기로 작성되어야 합니다.
Task는 철학적으로 모나드의 개념을 차용했고 모나드는 코드에 전파되는 형질이 있지요.
요즘은 라이브러리가 비동기 지원이 잘 되어 있어서 동기 코드를 작성하지 말라고 말하는 편이 좋습니다.
2개의 좋아요
조언 감사합니다.
제가 호출하는 client 쪽에 이미 동기/비동기 모두 지원하고 있어서
저도 동일하게 동기/비동기를 모두 지원하려고 했는데
약간 바보같은 생각이었던 것… =ㅁ=;;;
그냥 비동기 메서드만 작성하고 가죠다 쓰는 쪽에서 알아서 하라고 하는 게 베스트 일 거 같네요. ㅇㅅㅇ/
2개의 좋아요