यह संभवत: टीएल है, कई के लिए डॉ, लेकिन, मैं की तुलना लगता है await
के साथ BackgroundWorker
इस का पालन पर सेब और संतरे और मेरे विचारों की तुलना की तरह है:
BackgroundWorker
किसी एक कार्य को करने के लिए है, जिसे आप थ्रेड पूल थ्रेड पर पृष्ठभूमि में प्रदर्शन करना चाहते हैं। async
/ await
अतुल्यकालिक संचालन पर अतुल्यकालिक प्रतीक्षा के लिए एक वाक्यविन्यास है। वे ऑपरेशन थ्रेड पूल थ्रेड का उपयोग कर सकते हैं या नहीं कर सकते हैं या किसी अन्य थ्रेड का उपयोग भी कर सकते हैं । तो, वे सेब और संतरे हैं।
उदाहरण के लिए, आप निम्न के साथ कुछ कर सकते हैं await
:
using (WebResponse response = await webReq.GetResponseAsync())
{
using (Stream responseStream = response.GetResponseStream())
{
int bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length);
}
}
लेकिन, आप संभवतः कभी ऐसा नहीं करेंगे कि पृष्ठभूमि कार्यकर्ता में, आप संभवतः .NET 4.0 (पूर्व await
) में ऐसा कुछ करेंगे।
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);
सूचना दोनों वाक्यविन्यास और कैसे आप उपयोग नहीं कर सकते के बीच तुलना में निपटान के disjointness using
बिना async
/ await
।
लेकिन, आप ऐसा कुछ नहीं करेंगे BackgroundWorker
। BackgroundWorker
आमतौर पर एक लंबे समय तक चलने वाले ऑपरेशन को मॉडलिंग करने के लिए है जिसे आप यूआई जवाबदेही को प्रभावित नहीं करना चाहते हैं। उदाहरण के लिए:
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 / प्रतीक्षा के साथ, BackgroundWorker
आपके लिए थ्रेड बना रहा है।
अब, आप इसके बजाय TPL का उपयोग कर सकते हैं:
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);
किस स्थिति में TaskScheduler
आपके लिए थ्रेड बना रहा है (डिफ़ॉल्ट मानकर TaskScheduler
), और await
निम्नानुसार उपयोग कर सकता है:
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"
मेरी राय में, एक बड़ी तुलना यह है कि आप प्रगति की रिपोर्ट कर रहे हैं या नहीं। उदाहरण के लिए, आपके पास 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();
लेकिन, आप इनमें से कुछ के साथ सौदा नहीं करेंगे क्योंकि आप बैकग्राउंड वर्कर कंपोनेंट को फॉर्म की डिज़ाइन सतह पर ड्रैग-एंड-ड्रॉप कर देंगे - ऐसा कुछ जो आप async
/ await
और साथ नहीं कर सकते Task
... यानी आपने जीता ' t मैन्युअल रूप से ऑब्जेक्ट बनाएँ, गुण सेट करें और ईवेंट हैंडलर सेट करें। आप केवल के शरीर में भर देंगे DoWork
, RunWorkerCompleted
और ProgressChanged
ईवेंट हैंडलर्स।
यदि आपने "परिवर्तित" कर दिया है तो async / प्रतीक्षा में, आप कुछ ऐसा करेंगे:
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"
एक डिजाइनर सतह पर एक घटक को खींचने की क्षमता के बिना, यह वास्तव में पाठक पर निर्भर है कि वह "बेहतर" है। लेकिन, कि, मेरे लिए, के बीच तुलना है await
और BackgroundWorker
, नहीं है कि क्या आप में निर्मित तरीकों की तरह इंतजार कर सकते हैं Stream.ReadAsync
। उदाहरण के लिए यदि आप BackgroundWorker
इच्छानुसार उपयोग कर रहे थे , तो उपयोग करने के लिए परिवर्तित करना कठिन हो सकता है await
।
अन्य विचार: http://jeremybytes.blogspot.ca/2012/05/backgroundworker-component-im-not-dead.html