0

我有一个异步运行的 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);

它是否正确?这对我来说似乎是错误的。

4

2 回答 2

0

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

第二种方法也很麻烦,因为

  • 您的进度报告是武断且不切实际的
  • 即使是 100%,它也不能保证工作已经完成,因为在 100% 时它不知道工作是否已经完成。

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

解决方案是:

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

您还必须注意从后台线程与 UI 线程通信以及在 Windows 窗体中使用 Invoke 以及在 WPF 中使用 Dispatcher 的问题。

于 2011-05-11T23:02:27.553 回答
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 方法之后直接处理。您不需要轮询该IsCompleted属性。

于 2011-05-11T23:20:13.250 回答