IAsyncresult - 在不冻结UI的情况下进行轮询?

时间:2011-05-11 22:55:27

标签: c# wcf iasyncresult

我有一个异步运行的Windows svc(我编辑了方法及其参数以使它们异步),有点像:http://msdn.microsoft.com/en-us/library/ms731177.aspx

但是,我调用我想异步运行的任务(对服务/服务器的调用),然后更新UI(使用后台工作者的ReportProgress() - 所有这些都发生在dowork()方法中背景工作者)。但是,我调用Endxxx方法来获得结果,但问题是,我的代码不应该是这样吗?

while (!asyncresult.IsCompleted) { // Do all UI updating etc here... }

// Call endXXX here.

但是,这种方法会锁定UI。目前,我的代码是这样的(并没有锁定UI):

 IAsyncResult res = null;

                try
                {

                    res = serviceX.BeginXXX(ResultCallBack, "");
                }
                catch (FaultException<ManagementException> managementEx)
                {
                    Logger.Error(managementEx.Detail.ToString());
                    MessageBox.Show("Could not add printer. See log.");
                }



                    InstallBackgoundWorker.ReportProgress(90);
                    InstallBackgoundWorker.ReportProgress(91);
                    InstallBackgoundWorker.ReportProgress(93);

                    InstallBackgoundWorker.ReportProgress(94);
                    InstallBackgoundWorker.ReportProgress(95);
                    InstallBackgoundWorker.ReportProgress(96);
                    InstallBackgoundWorker.ReportProgress(97);



                    if (res.IsCompleted)
                    {
                        ResultCallBack(res);
                    }
                    InstallBackgoundWorker.ReportProgress(100);

这是对的吗?这对我来说似乎不对。

2 个答案:

答案 0 :(得分:0)

不,你不应该采取第一种方法,因为它违背了以异步方式调用方法的目标。

以来,第二种方法也很麻烦
  • 您的进度报告是任意且不切实际的
  • 即使100%也不能保证工作完成,因为在100%时它不知道工作是否已经完成。

除非异步提供异步作业,否则无法显示异步作业的进度报告。

解决方案是:

  • 显示不确定进度条(也称为微调器)
  • 在回调中报告结果的用户

您还必须了解从后台线程与UI线程进行通信的问题,并在Windows窗体中使用Invoke并在WPF中使用Dispatcher。

答案 1 :(得分:0)

我不确定您是否正确使用了异步模式。看起来应该是这样的:

void Start()
{
    System.IO.Stream s = ...;
    byte[] buf = ...;

    // start the IO.

    s.BeginRead(buf, 0, buf.Length, res =>
        {
            // this gets called when it's finished,
            // but you're in a different thread.

            int len = s.EndRead(res);

            // so you must call Dispatcher.Invoke
            // to get back to the UI thread.

            Dispatcher.Invoke((Action)delegate
                {
                    // perform UI updates here.
                });
        }, null);

    // the IO is started (and maybe finished) here,
    // but you probably don't need to put anything here.
}

Stream写,因为我不知道你的对象的签名,但希望你明白了!您需要在调用Begin方法后直接在回调中处理完成操作, not 。您不应该轮询IsCompleted属性。