완성 된 Task
(아닌 Task<T>
) 을 만들고 싶습니다 . 이를 위해 .NET에 내장 된 것이 있습니까?
관련 질문 : 완료된 작업 생성 <T>
ValueTask
완료된 작업 (예 : 코드가 본질적으로 동기가되도록 이미 보유한 값)이 있으므로 할당이 절약됩니다.
완성 된 Task
(아닌 Task<T>
) 을 만들고 싶습니다 . 이를 위해 .NET에 내장 된 것이 있습니까?
관련 질문 : 완료된 작업 생성 <T>
ValueTask
완료된 작업 (예 : 코드가 본질적으로 동기가되도록 이미 보유한 값)이 있으므로 할당이 절약됩니다.
답변:
닷넷 (V4.6)의 최신 버전 단지를 추가, 내장 Task.CompletedTask :
Task completedTask = Task.CompletedTask;
이 속성은 잠금이없는 싱글 톤으로 구현되므로 거의 항상 동일한 완성 된 작업을 사용하게됩니다.
Task.CompletedTask
만 여전히 내부에 있습니다.
Task<T>
암시 적으로 Task
로 변환 가능하므로 Task<T>
( T
임의의 값으로) 완성 된 것을 사용하십시오. 이와 같은 것을 사용하여 실제 결과가 어딘가에 있다는 사실을 숨길 수 있습니다.
private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
return completedTask;
}
결과를 공개하지 않고 작업이 항상 완료되었으므로 단일 작업을 캐시하고 재사용 할 수 있습니다.
.NET 4.0을 사용 중이고없는 경우 FromResult
다음을 사용하여 직접 만들 수 있습니다 TaskCompletionSource
.
public static Task<T> FromResult<T>(T value)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(value);
return tcs.Task;
}
이를 위해 내가 선호하는 방법은 Task.WhenAll()
인수없이 호출 하는 것입니다. MSDN 문서 상태는 "제공된 배열 / 열거 더 작업을 포함하지 않는 경우, 반환 작업은 RanToCompletion 상태로 즉시 전환이 호출자에게 반환의 뜻 전에.". 그것은 당신이 원하는 것 같습니다.
업데이트 : Microsoft의 Reference Source 에서 소스를 찾았습니다 . Task.WhenAll에 다음이 포함되어 있습니다.
return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
Task.CompletedTask :
new WhenAllPromise(tasks);
따라서 Task.CompletedTask는 실제로 내부이지만 인수없이 WhenAll ()을 호출하면 노출됩니다.
Task.FromResult (.NET 4.5)를 사용하여 완료된을 반환 할 수 있습니다 Task<T>
.
제네릭이 아닌을 필요로하는 경우 의 하위 클래스 이므로 Task
항상 사용 Task.FromResult(0)
하거나 유사 할 수 있습니다 .Task<T>
Task
Stephen Cleary 의 훌륭한 라이브러리 AsyncEx 에서 Nito.AsyncEx.TaskConstants.Completed 를 사용할 수 있습니다 .
어때요?
#pragma warning disable 1998
public async Task emptyTask() {
}
#pragma warning restore 1998
마음에 들지 않으면 경고 억제를 생략 할 수 있습니다.
async
도 사용하지 않더라도 전체 상태 머신 장치가 여전히 생성되므로 빈 작업을 반환하는 것이 리소스 부족 시나리오에 더 효과적입니다.
It seems like the answer I'm getting from everyone is that using a garbage value like this is the correct way. That there isn't a way to do this without the garbage value is disappointing -- oh well.
이것이 어떤 문제라고 생각하십니까? 단일Task
을 캐시하면 전체 프로그램이 1 비트의 추가 메모리를 차지합니다. 즉 없습니다 아무것도 . 또한 그렇게하지 않고 완성 된 작업을 만들 수 있습니다.