Ben karşılaştırarak düşünüyorum birçoğu için DR ancak; Bu büyük olasılıkla TL awaitile BackgroundWorker: Bu takip üzerine elma ve portakal ve düşüncelerimi karşılaştırmaya benzer
BackgroundWorker arka planda gerçekleştirmek istediğiniz tek bir görevi bir iş parçacığı havuzu iş parçacığında modellemek içindir. async/ await, eşzamansız olarak eşzamansız işlemleri bekleyen bir sözdizimidir. Bu işlemler bir iş parçacığı havuzu iş parçacığı kullanabilir veya kullanmayabilir veya başka bir iş parçacığı kullanabilir . Yani, bunlar elma ve portakal.
Örneğin, aşağıdakine benzer bir şey yapabilirsiniz: await :
using (WebResponse response = await webReq.GetResponseAsync())
{
using (Stream responseStream = response.GetResponseStream())
{
int bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length);
}
}
Ancak, büyük olasılıkla bir arka plan çalışanında muhtemelen .NET 4.0'da (öncesinde await) böyle bir şey yapacağınızı modellemezsiniz :
webReq.BeginGetResponse(ar =>
{
WebResponse response = webReq.EndGetResponse(ar);
Stream responseStream = response.GetResponseStream();
responseStream.BeginRead(buffer, 0, buffer.Length, ar2 =>
{
int bytesRead = responseStream.EndRead(ar2);
responseStream.Dispose();
((IDisposable) response).Dispose();
}, null);
}, null);
İki sözdizimi ve / usingolmadan nasıl kullanamayacağınızla karşılaştırıldığında, elden çıkarmanın ayrıklığına dikkat edin .asyncawait
Ama böyle bir şey yapmazdın BackgroundWorker . BackgroundWorkergenellikle kullanıcı arayüzü yanıt hızını etkilemek istemediğiniz tek bir uzun süreli işlemi modellemek içindir. Örneğin:
worker.DoWork += (sender, e) =>
{
int i = 0;
// simulate lengthy operation
Stopwatch sw = Stopwatch.StartNew();
while (sw.Elapsed.TotalSeconds < 1)
++i;
};
worker.RunWorkerCompleted += (sender, eventArgs) =>
{
// TODO: do something on the UI thread, like
// update status or display "result"
};
worker.RunWorkerAsync();
Async / await ile kullanabileceğiniz gerçekten hiçbir şey yok, sizin BackgroundWorkeriçin iş parçacığı oluşturuyor.
Artık bunun yerine TPL'yi kullanabilirsiniz:
var synchronizationContext = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
int i = 0;
// simulate lengthy operation
Stopwatch sw = Stopwatch.StartNew();
while (sw.Elapsed.TotalSeconds < 1)
++i;
}).ContinueWith(t=>
{
// TODO: do something on the UI thread, like
// update status or display "result"
}, synchronizationContext);
Bu durumda, TaskScheduleriş parçacığını sizin için oluşturuyor (varsayılanı varsayarak TaskScheduler) ve awaitaşağıdaki gibi kullanabilirsiniz :
await Task.Factory.StartNew(() =>
{
int i = 0;
// simulate lengthy operation
Stopwatch sw = Stopwatch.StartNew();
while (sw.Elapsed.TotalSeconds < 1)
++i;
});
// TODO: do something on the UI thread, like
// update status or display "result"
Kanımca, büyük bir karşılaştırma ilerlemeyi bildirip bildirmediğinizdir. Örneğin, aşağıdakilere sahip olabilirsiniz BackgroundWorker like:
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.ProgressChanged += (sender, eventArgs) =>
{
// TODO: something with progress, like update progress bar
};
worker.DoWork += (sender, e) =>
{
int i = 0;
// simulate lengthy operation
Stopwatch sw = Stopwatch.StartNew();
while (sw.Elapsed.TotalSeconds < 1)
{
if ((sw.Elapsed.TotalMilliseconds%100) == 0)
((BackgroundWorker)sender).ReportProgress((int) (1000 / sw.ElapsedMilliseconds));
++i;
}
};
worker.RunWorkerCompleted += (sender, eventArgs) =>
{
// do something on the UI thread, like
// update status or display "result"
};
worker.RunWorkerAsync();
Ancak, bunlardan bazılarıyla uğraşmazsınız çünkü arka plan çalışan bileşenini bir formun tasarım yüzeyine sürükleyip bırakacaksınız - async/ ile yapamayacağınız bir şey awaitve Task... yani kazandınız ' t Nesneyi el ile oluşturma, özellikleri ayarlama ve olay işleyicileri ayarlama. sadece bedenini doldurursun DoWork,RunWorkerCompleted ve ProgressChangedolay işleyicileri.
Bunu eşzamansız / beklemeye "dönüştürdüyseniz" şöyle bir şey yaparsınız:
IProgress<int> progress = new Progress<int>();
progress.ProgressChanged += ( s, e ) =>
{
// TODO: do something with e.ProgressPercentage
// like update progress bar
};
await Task.Factory.StartNew(() =>
{
int i = 0;
// simulate lengthy operation
Stopwatch sw = Stopwatch.StartNew();
while (sw.Elapsed.TotalSeconds < 1)
{
if ((sw.Elapsed.TotalMilliseconds%100) == 0)
{
progress.Report((int) (1000 / sw.ElapsedMilliseconds))
}
++i;
}
});
// TODO: do something on the UI thread, like
// update status or display "result"
Bir bileşeni Tasarımcı yüzeyine sürükleme yeteneği olmadan hangisinin "daha iyi" olduğuna karar vermek gerçekten okuyucuya bağlıdır. Ama, bu, bana göre, aralarında karşılaştırmadır awaitve BackgroundWorkerdeğil sizi bekliyor yerleşik olabilir gibi yöntemlerle ister Stream.ReadAsync. örneğin,BackgroundWorker , amaçlandığı gibi , dönüştürmek zor olabilir await.
Diğer düşünceler: http://jeremybytes.blogspot.ca/2012/05/backgroundworker-component-im-not-dead.html