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.