问题描述
我想使用.NET的FTP Libary( HTTP://netftp.$c$cplex.com )。该libary提供BeginOpenRead(字符串的AsyncCallback,对象)下载使用异步编程模型的内容。我执行回调是基本相同的例子:
I want to use the .NET-FTP Libary (http://netftp.codeplex.com). The libary offers BeginOpenRead(string,AsyncCallback,object) to download the contents using the Asynchronous Programming Model. My implementation of the Callback is basically the same as the example:
static void BeginOpenReadCallback(IAsyncResult ar) {
FtpClient conn = ar.AsyncState as FtpClient;
try {
if (conn == null)
throw new InvalidOperationException("The FtpControlConnection object is null!");
using (Stream istream = conn.EndOpenRead(ar)) {
byte[] buf = new byte[8192];
try {
DateTime start = DateTime.Now;
while (istream.Read(buf, 0, buf.Length) > 0) {
double perc = 0;
if (istream.Length > 0)
perc = (double)istream.Position / (double)istream.Length;
Console.Write("\rTransferring: {0}/{1} {2}/s {3:p} ",
istream.Position.FormatBytes(),
istream.Length.FormatBytes(),
(istream.Position / DateTime.Now.Subtract(start).TotalSeconds).FormatBytes(),
perc);
}
}
finally {
Console.WriteLine();
istream.Close();
}
}
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
finally {
m_reset.Set();
}
}
异步方法的工作完成
后,这将是巨大的,如果已完成的事件被触发(由启动异步方法,以获得没有问题的UI线程)的结果传递给Main-线。就像BackgroundWorker的不(用RunWorkerCompleted)。
After the work of the async Method is completed, it would be great if a Completed event is fired (by the thread that started the asynchronous method in order to get no problems with the UI) to pass the results to the Main-Thread. Just like BackgroundWorker does (using RunWorkerCompleted).
我怎么能认识到这一点?
How can I realize this?
推荐答案
尝试转换的的模式进入的模式(更多信息):
Try converting the APM pattern into the TAP pattern (more info):
static public Task<Stream> OpenReadAsync(FtpClient ftpClient, string url)
{
return Task.Factory.FromAsync(
(asyncCallback, state) =>
ftpClient.BeginOpenRead(url, asyncCallback, state),
(asyncResult) =>
ftpClient.EndOpenRead((asyncResult));
}
然后你可以用异步/计谋
键,不必担心同步方面:
Then you can use async/await
and don't have to worry about synchronization context:
Stream istream = await OpenReadAsync(ftpClient, url);
另外,您还可以使用 Stream.ReadAsync :
while (await istream.ReadAsync(buf, 0, buf.Length) > 0)
{
// ...
}
的BackgroundWorker
是基于任务的API所取代,所以它可能是一个双赢的局面(详细信息:的和的)。
BackgroundWorker
is superseded by Task-based API, so it may be a win-win situation (more info: Task.Run vs BackgroundWorker and here).
[更新] 如果您在VS2012 +工作,你可以针对.NET 4.0的,并仍然使用现代语言和第三方物流的功能,如异步/计谋
。我经历过这一点,我强烈推荐它,因为它使将来移植到.NET 4.5的微风。
[UPDATE] If you work in VS2012+, you can target .NET 4.0 with Microsoft.Bcl.Async and still use the modern language and TPL features like async/await
. I've been through that and I'd highly recommend it as it makes the future porting to .NET 4.5 a breeze.
否则,您可以使用 Task.ContinueWith(回调,TaskScheduler.FromCurrentSynchronizationContext())
继续在UI线程上。这里有一个相关的例子。
Otherwise, you can use Task.ContinueWith(callback, TaskScheduler.FromCurrentSynchronizationContext())
to continue on the UI thread. Here's a related example.
这篇关于的AsyncCallback来的BackgroundWorker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!