Tamamlanmış bir Görev Oluştur <T>


125

Bir yöntem uyguluyorum Task<Result> StartSomeTask()ve sonucu, yöntem çağrılmadan önce zaten biliyorum. Zaten tamamlanmış bir Görev <T> nasıl oluşturabilirim ?

Şu anda yaptığım şey bu:

private readonly Result theResult = new Result();

public override Task<Result> StartSomeTask()
{
    var task = new Task<Result>(() => theResult);
    task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread);
    return task;
}

Daha iyi bir çözüm var mı?


6
Unutmayın, bu sorunun yanıtları, Task <T> Görev'den miras aldığından, düz bir Görev (<T> yok) oluşturmak için gayet iyi çalışır.
Tim Lovell-Smith

Bugün ValueTask, tamamlanmış görevler için (yani kodun esasen eşzamanlı olması için sahip olduğunuz değerler için) ve bu da size bir tahsisat kazandıracak.
nawfal

Yanıtlar:


111
private readonly Result theResult = new Result();

public override Task<Result> StartSomeTask()
{
    var taskSource = new TaskCompletionSource<Result>();
    taskSource.SetResult(theResult);
    return taskSource.Task;
}

@DanielLobo, itirazınızın ne olduğunu açıklarsanız bir cevap alabilirsiniz
user2023861

1
Aşağıdakinin daha basit ve çok daha fazla oy alması gerekmiyor mu? @ user2023861
Daniel Lobo

203

.NET 4.5'i hedeflerken şunları kullanabilirsiniz Task.FromResult:

public static Task<TResult> FromResult<TResult>(TResult result);

Başarısız bir görev oluşturmak için şunu kullanın Task.FromException:

public static Task FromException(Exception exception);
public static Task<TResult> FromException<TResult>(Exception exception);

.NET 4.6, Task.CompletedTaskgenel olmayan bir Task.

public static Task CompletedTask { get; }

.NET'in eski sürümleri için geçici çözümler:

  • .NET 4.0'ı Async Targetting Pack (veya AsyncCTP) ile hedeflerken TaskEx.FromResultbunun yerine kullanabilirsiniz .

  • Task.NET 4.6'dan önce jenerik olmayan almak için, ' Task<T>dan türetilen Taskve sadece Task.FromResult<object>(null)veya Task.FromResult(0).


13
Genel olmayan bir görevi döndürmek için Task.FromResult (0) gibi bir şey kullanmak daha iyidir. Parametre olarak "null" kullanmak, genel parametreyi belirleyemeyen derleyicinin kafasını karıştırabilir.
Whyllee

İstisnalar ne olacak? Zaman uyumsuz yöntemler, özel durumları yakalayan ve döndürülen Task. Bu, ilk beklemeden önce kod çalıştırıldığında bile olur. Task.FromResult döndüren yöntem, doğrudan özel durumlar oluşturabilir.
Robert Važan

@ RobertVažan İlginç bir uç durum. Muhtemelen, bilinen sonucunuzu bir yöntemden alıyorsanız ve bu yöntem istisnalar atıyorsa, düzeltilmesi gereken bir kusur vardır.
Gusdor

1
@ RobertVažan Gibi FromExceptiondavranan FromResultancak hatalı bir görevi temsil eden kendi yönteminizi kolayca yazabilirsiniz . Böyle bir yöntem, istisnanın sonuçta ortaya çıkan görevde temsil edilmesi için önemliyse, hata durumları için bunu basitçe döndürebilir.
Servy

1
Task.FromException .NET 4.5'te mevcut değil ... Belirtilmesi gerektiğini düşünüyorum.
STiLeTT

12

Geri dönüş değeri olmayan görevler için .NET 4.6, Task.CompletedTask'i ekledi .

Zaten TaskStatus.RanToCompletion'da bulunan bir görevi döndürür. Muhtemelen her seferinde aynı örneği döndürür, ancak belgeler sizi bu gerçeğe güvenmemeniz konusunda uyarır.



1

Task.WhenAll parametresiz çağrılması tamamlanmış bir görevi döndürür.

Task task = Task.WhenAll();

bu işe yarayacak olsa da, var olmayan görevleri beklemeyi gerektirdiğinden, kodu okurken insanların kafasını karıştırabilecek belirsiz bir çözüm
Adrian Hristov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.