यह संभवत: टीएल है, कई के लिए डॉ, लेकिन, मैं की तुलना लगता है 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