Ben karşılaştırarak düşünüyorum birçoğu için DR ancak; Bu büyük olasılıkla TL await
ile 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 / using
olmadan nasıl kullanamayacağınızla karşılaştırıldığında, elden çıkarmanın ayrıklığına dikkat edin .async
await
Ama böyle bir şey yapmazdın BackgroundWorker
. BackgroundWorker
genellikle 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 BackgroundWorker
iç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, TaskScheduler
iş parçacığını sizin için oluşturuyor (varsayılanı varsayarak TaskScheduler
) ve await
aş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 await
ve Task
... yani kazandınız ' t Nesneyi el ile oluşturma, özellikleri ayarlama ve olay işleyicileri ayarlama. sadece bedenini doldurursun DoWork
,RunWorkerCompleted
ve ProgressChanged
olay 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 await
ve BackgroundWorker
değ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