Böyle olduğu parçasını planı ayrı olabilir:
async Task<bool> WaitForItToWork()
{
bool succeeded = false;
while (!succeeded)
{
// do work
succeeded = outcome; // if it worked, make as succeeded, else retry
await Task.Delay(1000); // arbitrary delay
}
return succeeded;
}
Anlaşılan, bu iş parçacığı havuzu daha verimli kullanılmasıdır verecek tek yararı, her zaman gecikmesini yapmak için bütün bir iplik almaz çünkü olmak.
outcome
'u nasıl elde edeceğinize bağlı olarak, bu işi async/await
kullanarak gerçekleştirmenin çok daha verimli yolları olabilir. Genellikle GetOutcomeAsync()
gibi bir web servisini, veritabanını veya soket çağrısını doğal bir şekilde eşzamanlı olmayan bir şekilde yapabilirsiniz, böylece var outcome = await GetOutcomeAsync()
'u yaparsınız.
WaitForItToWork
'un derleyici tarafından parçalara ayrılacağı ve await
satırının eşzamansız olarak devam edeceği dikkate alınmalıdır. Here's belki de dahili olarak nasıl yapıldığına dair en iyi açıklama. Şey, genellikle kodunuzun bir noktasında, async görevinin sonucu üzerinde senkronize etmeniz gerekecek. Örn .:
private void Form1_Load(object sender, EventArgs e)
{
Task<bool> task = WaitForItToWork();
task.ContinueWith(_ => {
MessageBox.Show("WaitForItToWork done:" + task.Result.toString()); // true or false
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Sadece bu yapmış olabilir:
private async void Form1_Load(object sender, EventArgs e)
{
bool result = await WaitForItToWork();
MessageBox.Show("WaitForItToWork done:" + result.toString()); // true or false
}
ancak çok Form1_Load
bir zaman uyumsuz yöntem yapmak olacağını.
[GÜNCELLEME]
Aşağıda async/await
aslında bu durumda ne yaptığını göstermek için benim girişimidir. Aynı mantıksal iki sürümü oluşturdu, WaitForItToWorkAsync
(async/await
kullanarak) ve WaitForItToWorkAsyncTap
(TAP pattern kullanarak async/await
). İkinci versiyonun aksine, frist versiyonu oldukça önemsizdir. Böylece, async/await
büyük ölçüde derleyicinin sözdizimsel şekeri iken, asenkron kodları yazmayı ve anlamayı daha kolay hale getirir.
// fake outcome() method for testing
bool outcome() { return new Random().Next(0, 99) > 50; }
// with async/await
async Task<bool> WaitForItToWorkAsync()
{
var succeeded = false;
while (!succeeded)
{
succeeded = outcome(); // if it worked, make as succeeded, else retry
await Task.Delay(1000);
}
return succeeded;
}
// without async/await
Task<bool> WaitForItToWorkAsyncTap()
{
var context = TaskScheduler.FromCurrentSynchronizationContext();
var tcs = new TaskCompletionSource<bool>();
var succeeded = false;
Action closure = null;
closure = delegate
{
succeeded = outcome(); // if it worked, make as succeeded, else retry
Task.Delay(1000).ContinueWith(delegate
{
if (succeeded)
tcs.SetResult(succeeded);
else
closure();
}, context);
};
// start the task logic synchronously
// it could end synchronously too! (e.g, if we used 'Task.Delay(0)')
closure();
return tcs.Task;
}
// start both tasks and handle the completion of each asynchronously
private void StartWaitForItToWork()
{
WaitForItToWorkAsync().ContinueWith((t) =>
{
MessageBox.Show("WaitForItToWorkAsync complete: " + t.Result.ToString());
}, TaskScheduler.FromCurrentSynchronizationContext());
WaitForItToWorkAsyncTap().ContinueWith((t) =>
{
MessageBox.Show("WaitForItToWorkAsyncTap complete: " + t.Result.ToString());
}, TaskScheduler.FromCurrentSynchronizationContext());
}
// await for each tasks (StartWaitForItToWorkAsync itself is async)
private async Task StartWaitForItToWorkAsync()
{
bool result = await WaitForItToWorkAsync();
MessageBox.Show("WaitForItToWorkAsync complete: " + result.ToString());
result = await WaitForItToWorkAsyncTap();
MessageBox.Show("WaitForItToWorkAsyncTap complete: " + result.ToString());
}
parçacığı üzerinde birkaç kelime. Burada açıkça oluşturulmuş ek bir konu yok.Dahili olarak, Task.Delay()
uygulama havuz iş parçacığı kullanabilir (Timer Queues kullandıklarından şüpheleniyorum), ancak bu özel örnekte (bir WinForms uygulaması), await
sonrasında devam aynı UI iş parçacığında gerçekleşir. Diğer uygulama ortamlarında (örneğin bir konsol uygulaması), farklı bir iş parçacığı üzerinde devam edebilir. Stephen Cleary tarafından IMO, this article, async/await
iş parçacığı kavramlarını anlamak için okunmalıdır. Görev asenkron ise
Bunu sadece this.WaitForItToWork() işlevini kullanarak söyler miyim? - async kitaplığı benim için iş parçacığıyla ilgilenir mi? – Chris
Bunu, 'this.WaitForItToWork() '' ı beklemek gibi çağırırsınız ve bu çağrıyı desteklemek için tüm çağrı zincirleri yeniden düzenlenmelidir ... Daha fazla bilgi içermek için cevabımı ayrıntılı olarak ele alacağım. – Noseratio
@Chris: "bekle" anahtar sözcüğünü kullanmayı unutmamalısınız. Genel kural: Her zaman "bekliyor", "async" işleviyle birleştirilmelidir. Yani, beklemek gibi bir şey yapmalısınız WaitForItToWork(); –