এই সম্ভবত TL হয়; অনেকের জন্য ডিআর, কিন্তু, আমি তুলনা মনে 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);
}
}
তবে, আপনি সম্ভবত কখনও মডেল করতেন না যে কোনও পটভূমি কর্মী হিসাবে আপনি সম্ভবত নেট নেট 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);
দুটি সিনট্যাক্সের মধ্যে এবং আপনি কীভাবে / usingছাড়া ব্যবহার করতে পারবেন না তার মধ্যে তুলনা করে ডিসপোজারের বিরক্তি লক্ষ্য করুন ।asyncawait
তবে, আপনি এরকম কিছু করবেন না 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();
আপনার পক্ষে অ্যাসিঙ্ক ব্যবহার / অপেক্ষা করতে পারবেন এমন কিছুই নেই, আপনার BackgroundWorkerজন্য থ্রেড তৈরি করছে।
এখন, আপনি পরিবর্তে টিপিএল ব্যবহার করতে পারেন:
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... সহ করতে পারবেন না ... অর্থাৎ আপনি জিতেছেন ' টি ম্যানুয়ালি অবজেক্টটি তৈরি করুন, বৈশিষ্ট্যগুলি সেট করুন এবং ইভেন্ট হ্যান্ডলারগুলি সেট করুন। আপনি শুধুমাত্র দেহের ভরিয়ে তুলবে 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