的AsyncCallback来的BackgroundWorker

的AsyncCallback来的BackgroundWorker

本文介绍了的AsyncCallback来的BackgroundWorker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用.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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 17:37