尝试转换APM http://msdn.microsoft.com/en-us/library/ms228963%28v=vs.110%29.aspx模式进入TAP http://msdn.microsoft.com/en-us/library/hh873175%28v=vs.110%29.aspx图案 (更多信息 http://blogs.msdn.com/b/pfxteam/archive/2011/06/27/using-tasks-to-implement-the-apm-pattern.aspx):
static public Task<Stream> OpenReadAsync(FtpClient ftpClient, string url)
{
return Task.Factory.FromAsync(
(asyncCallback, state) =>
ftpClient.BeginOpenRead(url, asyncCallback, state),
(asyncResult) =>
ftpClient.EndOpenRead((asyncResult));
}
然后你可以使用async/await
并且不必担心同步上下文:
Stream istream = await OpenReadAsync(ftpClient, url);
此外,您可以使用Stream.ReadAsync http://msdn.microsoft.com/en-us/library/hh137813%28v=vs.110%29.aspx:
while (await istream.ReadAsync(buf, 0, buf.Length) > 0)
{
// ...
}
BackgroundWorker
被基于任务的 API 取代,因此这可能是一个双赢的局面(更多信息:Task.Run 与 BackgroundWorker http://blog.stephencleary.com/search/label/Task.Run%20vs%20BackgroundWorker and here https://stackoverflow.com/a/21327014/1768303).
[UPDATE]如果您在 VS2012+ 中工作,则可以使用 .NET 4.0 为目标微软Bcl.Async http://www.nuget.org/packages/microsoft.bcl.async并且仍然使用现代语言和 TPL 功能,例如async/await
。我已经经历过这一点,并且我强烈推荐它,因为它使将来移植到 .NET 4.5 变得轻而易举。
否则,您可以使用Task.ContinueWith(callback, TaskScheduler.FromCurrentSynchronizationContext())
继续 UI 线程。这是一个相关例子 https://stackoverflow.com/a/21346870/1768303.