संपादित मैं मजबूर कर की उचित तरीके से इस तरह एसिंक्रोनस रूप से कार्यकर्ता आह्वान एक Task.Run साथ है, के लिए इंतजार है लगता है:Async/प्रगति/रद्दीकरण के लंबे समय से चल एपीआई तरीकों के लिए इंतजार
await Task.Run(() => builder.Build(dlg.FileName, cts.Token, new Progress(ReportProgress)));
http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/10293335.aspx से कुछ प्रकाश मिला।
यह आसान होना चाहिए, लेकिन मैं async/await के लिए नया हूं इसलिए मेरे साथ सहन करें। मैं कुछ लंबे समय से चल रहे संचालन के साथ एक एपीआई उजागर करने वाली कक्षा पुस्तकालय का निर्माण कर रहा हूं।
public void DoSomething(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = (BackgroundWorker)sender;
// e.Argument is any object as passed by consumer via RunWorkerAsync...
do
{
// ... do something ...
// abort if requested
if (bw.CancellationPending)
{
e.Cancel = true;
break;
} //eif
// notify progress
bw.ReportProgress(nPercent);
}
}
और ग्राहक कोड की तरह था:
BackgroundWorker worker = new BackgroundWorker
{ WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
worker.DoWork += new DoWorkEventHandler(_myWorkerClass.DoSomething);
worker.ProgressChanged += WorkerProgressChanged;
worker.RunWorkerCompleted += WorkerCompleted;
worker.RunWorkerAsync(someparam);
अब मैं करना चाहते हैं अतीत में, मैं प्रगति इस सरलीकृत कोड टुकड़ा में रिपोर्टिंग और निरस्तीकरण, की तरह से निपटने के लिए एक BackgroundWorker इस्तेमाल किया नए एसिंक पैटर्न का लाभ उठाएं। तो, सबसे पहले यहां यह है कि मैं अपने एपीआई में एक साधारण लंबी चलने वाली विधि कैसे लिखूंगा; यहाँ मैं सिर्फ सिर्फ एक वास्तविक दुनिया प्रक्रिया अनुकरण करने के लिए जहाँ मैं कुछ प्रसंस्करण के साथ एक फ़ाइल स्वरूप परिवर्तित करना होगा लाइन द्वारा एक फ़ाइल लाइन पढ़ रहा हूँ,:
public async Task DoSomething(string sInputFileName, CancellationToken? cancel, IProgress progress)
{
using (StreamReader reader = new StreamReader(sInputFileName))
{
int nLine = 0;
int nTotalLines = CountLines(sInputFileName);
while ((sLine = reader.ReadLine()) != null)
{
nLine++;
// do something here...
if ((cancel.HasValue) && (cancel.Value.IsCancellationRequested)) break;
if (progress != null) progress.Report(nLine * 100/nTotalLines);
}
return nLine;
}
}
इस नमूने के लिए, यह कहना एक डमीवर्कर वर्ग की एक विधि है।
private void ReportProgress(int n)
{
Dispatcher.BeginInvoke((Action)(() => { _progress.Value = n; }));
}
private async void OnDoSomethingClick(object sender, RoutedEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog { Filter = "Text Files (*.txt)|*.txt" };
if (dlg.ShowDialog() == false) return;
// show the job progress UI...
CancellationTokenSource cts = new CancellationTokenSource();
DummyWorker worker = new DummyWorker();
await builder.Build(dlg.FileName, cts.Token, new Progress(ReportProgress));
// hide the progress UI...
}
IProgress इंटरफेस के लिए कार्यान्वयन, http://blog.stephencleary.com/2010/06/reporting-progress-from-tasks.html से आता है तो आप उस URL का उल्लेख कर सकते: अब, यहाँ मेरे मुवक्किल कोड (एक WPF परीक्षण ऐप) है। वैसे भी, इस उपयोग परीक्षण में यूआई प्रभावी ढंग से अवरुद्ध है और मुझे कोई प्रगति दिखाई नहीं दे रही है। तो खपत कोड के संदर्भ में, इस तरह के एक परिदृश्य के लिए पूरी तस्वीर क्या होगी?
हाँ, 'कार्य। रुन()' ऐसा करने का तरीका है। या संभवत: 'LongRunning' विकल्प सेट के साथ 'कार्य। फैक्टरी। स्टार्टन्यू()', यदि कार्रवाई वास्तव में लंबी है। – svick