এই সম্ভবত 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
ছাড়া ব্যবহার করতে পারবেন না তার মধ্যে তুলনা করে ডিসপোজারের বিরক্তি লক্ষ্য করুন ।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();
আপনার পক্ষে অ্যাসিঙ্ক ব্যবহার / অপেক্ষা করতে পারবেন এমন কিছুই নেই, আপনার 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