Task<T>
düzgünce "başlatılmış, tamamlanmış olabilir" hesaplamasını, diğer görevler, işlevler ile eşleştirilen vb. Ile birlikte oluşturabilir. Buna karşılık, F # async
monad "daha sonra başlayabilir, şimdi çalışıyor olabilir" hesaplama ve CancellationToken
ile birlikte . C# 'da, genellikle Task
ile çalışan her işlev aracılığıyla CancellationToken
iş parçacığı. C# takımı neden hesabı Task
monad'ına sarmayı seçti, ama CancellationToken
?Task <T> Monad'da neden bir CancellationToken bulunmuyor?
cevap
Daha çok veya daha azı, C# async
yöntemleri için CancellationToken
örtük kullanımını kapsüllediler. Şunu bir düşünün: zaman uyumsuz olmayan lamda için
var cts = new CancellationTokenSource();
cts.Cancel();
var token = cts.token;
var task1 = new Task(() => token.ThrowIfCancellationRequested());
task1.Start();
task1.Wait(); // task in Faulted state
var task2 = new Task(() => token.ThrowIfCancellationRequested(), token);
task2.Start();
task2.Wait(); // task in Cancelled state
var task3 = (new Func<Task>(async() => token.ThrowIfCancellationRequested()))();
task3.Wait(); // task in Cancelled state
, ben iptal new Task()
(veya Task.Run
) bir argüman olarak vererek, doğru yaymak için açıkça task2
ile token
ilişkilendirmek zorunda kaldı. task3
ile kullanılan bir async
lambda için, async/await
altyapı kodunun bir parçası olarak otomatik olarak gerçekleşir. uyumsuz olmayan hesaplama new Task()
/Task.Run
lambda için görev kurucu veya Task.Run
geçirilen aynı belirteci olmak zorunda ise
Ayrıca, herhangitoken
, bir async
yöntem için iptal yaymak olacaktır. Kooperatif iptal modelini uygulamak için elbette el ile token.ThrowIfCancellationRequested()
'u aramak zorundayız. C# ve TPL takımlarının neden bu şekilde uygulamaya karar verdiklerini söyleyemem ama sanırım, async/await
'un sözdizimini aşırı derecede karmaşıklaştırmayı değil, yeterince esnek tutmayı amaçlıyorlardı.
F # ile ilgili olarak, Tomas Petricek'in bağlı olduğunuz blog post resminde gösterilen zaman uyumsuz iş akışının oluşturulmuş IL kodunu incelemedim. Yine de, anlayabildiğim kadarıyla, token otomatik olarak yalnızca iş akışının belirli noktalarında test edilir, bunlar C# 'da await
'a karşılık gelir (analojiyle, token.ThrowIfCancellationRequested()
'u her # await
C#' da el ile çağırıyor olabiliriz). Bu, CPU'ya bağlı herhangi bir işlemin hemen iptal edilmeyeceği anlamına gelir. Aksi halde, F #, her IL talimatından sonra token.ThrowIfCancellationRequested()
yaymak zorunda kalacaktır, ki bu oldukça önemli bir ek yük olacaktır.
CPU'ya bağlı iş için ne zaman ve neden beklemede/beklemede bulunmak istersiniz? – GregC
@GregC, her zaman bir UI uygulamasında CPU-bağlı çalışma yapmam gerekiyor: 'var pi = Task.Run (() => CalcPi (basamak, jeton), belirteç)'. – Noseratio
@GregC Bir paralelleştirme şeklidir. 'Bekle. Görev.Yani (görevler)'. – Aron
Görev başlangıçta sınıfta ek özellikler içerecek şekilde yapıldı, ancak daha sonra ek özellik desteği ile bir nesneyi toplamak için değiştirildi. Hepsi performans adına.
http://blogs.msdn.com/b/pfxteam/archive/2011/11/10/10235962.aspx (kağıda "yeniden yapılanma görevi" konusuna bakın) Joseph E. Hoag tarafından hazırlanan makale, .NET 4.5'te yapılan en iyileştirmelerle ilgili güzel bilgiler verir. Async/beklemedeki performansın son% 10'unu sıkıştırmaya çalışan herkes için iyi bir okuma olacağını düşünüyorum.
İptal işlevinin nasıl paketleneceğine karar verirken benzer bir düşünce işlemi uygulandığını farz ediyorum.
C# veya BCL ekibi için konuşamıyorum, ancak bunun yalnızca F # derleyicisinde mümkün olan bir performans optimizasyonu olduğunu veya performansın F # ekibine önemsiz olduğunu varsayıyorum. SRP, baby!
O Hoag gazetesini unutmuştum. Sürüş gibi göründüğü gibi Task nesnesini mümkün olduğunca küçük tutmak, bu nedenle İptal belirteci etrafında taşımak değil, bunun yerine async/beklemenin oluşturduğu durum makinesinde taşımaktı. –
- 1. Eylem <Task> uygulama
- 2. varsayılan (CancellationToken) Ben varsayılan <code>CancellationToken</code> oluşturduğunuzda
- 3. Polimorfik değerler neden Haskell'de bulunmuyor?
- 4. Resimlerim web sunucumda neden bulunmuyor?
- 5. TaskFactory.StartNew() içinde "cancellationToken" nedir?
- 6. C#: CancellationToken engelleme yöntemini iptal etmiyor
- 7. Neden özel rake görevim, lib/görevleri Rails 3'te bulunmuyor?
- 8. cancellationtoken timeout vs task.delay() ve zaman aşımı
- 9. Neden junit4 çift [] için Assert.assertArrayEquals() bulunmuyor?
- 10. Neden 'FileField' nesnesinin 'put' özelliği bulunmuyor?
- 11. Neden Cocoapod'lar gömülü içerik hakkında şikayette bulunmuyor?
- 12. CancellationToken özelliği nasıl kullanılır?
- 13. CancellationToken ayarlandığında keyfi bir istisna atmak kötü bir uygulama mı?
- 14. jQuery ajax bir veritabanından veri isteğinde bulunmuyor
- 15. StreamReader.ReadLineAsync'i CancellationToken ile iptal edebilir miyim?
- 16. Neden 'this', 'obj' nesnesine değil, 'object' nesnesine atıfta bulunmuyor
- 17. Scalaz'da Task ve IO arasındaki fark nedir?
- 18. Son birkaç satırlık bir PDF açıklaması bulunmuyor
- 19. Yüzde bulunmuyor div div ile
- 20. ObjectContext'te DbContext işlevleri bulunmuyor mu?
- 21. Angular2-jwt AuthHttp istekte bulunmuyor
- 22. TaskCanceledException neden oluşuyor?
- 23. VS 2015 Task Runner klavye kısayolları nelerdir?
- 24. C# Task gerçekte ne zaman başlıyor?
- 25. Pyinvoke @task dekoratör ile çoklu dekoratör kullanmak
- 26. ASP.NET: Global.asax'ta async Task çağrılabilir mi?
- 27. HttpClient, .net 4.0'da bulunmuyor: ne yapabilirim?
- 28. Dosya başka bir işlem tarafından FileSystemWatcher ve Task
- 29. 1px <hr> görünümü neden değişiyor?
- 30. WebClient sınıfı, Windows 8'de bulunmuyor
C# içinde, "var görev = yeni Görev (eylem, simge)" biçiminde bir CancellationToken * seçeneğiyle birlikte *, "daha sonra başlayabilir, şimdi çalışıyor olabilir". – Noseratio