C# 后台工作者在 DoWork 中设置 e.Result 并在 WorkCompleted 中取回价值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/856313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:22:22  来源:igfitidea点击:

C# Background worker setting e.Result in DoWork and getting value back in WorkCompleted

c#backgroundworker

提问by ant2009

C# 2008 SP1

C# 2008 SP1

I am using the background worker

我正在使用后台工作人员

If one of the conditions fails I will set e.cancel to true, and assign the string to the e.result. Everything works there.

如果条件之一失败,我会将 e.cancel 设置为 true,并将字符串分配给 e.result。一切都在那里工作。

However, when the workCompleted fires, I test for the e.Result and I get an exception "e.result throw an exception of type systeminvalidoperation".

但是,当 workCompleted 触发时,我测试 e.Result 并收到异常“e.result 抛出 systeminvalidoperation 类型的异常”。

I guess I could use a global variable to set in the DoWork and compare in the work completed. But this might not be threadsafe.

我想我可以使用全局变量在 DoWork 中设置并在已完成的工作中进行比较。但这可能不是线程安全的。

Can anyone tell me why I am getting this with the e.Result, and how can I solve this?

谁能告诉我为什么我用 e.Result 得到这个,我该如何解决这个问题?

Many thanks,

非常感谢,

    private void bgwPrepareCall_DoWork(object sender, DoWorkEventArgs e)
    {
        // Check to see if the called number is blocked. 
        // If the nubmer is blocked display error message.
        if (this.IsNoGateway(sipUsername, statusDisplay1.PhoneNumber))
        {
            // this.SetIdleState(DialerErrorMessage.GetErrorDescription(12));
            e.Cancel = true;
            e.Result = "NoGateway";
            return;
        }

        if (!this.IsInvalidTelephoneNumber(sipUsername, statusDisplay1.PhoneNumber))
        {
            // this.SetIdleState(DialerErrorMessage.GetErrorDescription(13));
            e.Cancel = true;
            e.Result = "InvalidNumber";
            return;
        }
    }

    private void bgwPrepareCall_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            if (e.Cancelled)
            {
                // Failed
                switch (e.Result.ToString())
                {
                    case "NoGateway":
                        Console.WriteLine("NoGateway: [ Failed ]");
                        break;

                    case "InvalidNumber":
                        Console.WriteLine("InvalidNumber: [ Failed ]");
                        break;

                    default:
                        Console.WriteLine("Unknown");
                        break;
                }
            }
            if (!e.Cancelled)
            {
                // Successfull
                Console.WriteLine("NoGateway: [ ok ]");    
                Console.WriteLine("InvalidNumber: [ ok ]");
            }
        }
        else
        {
            Console.WriteLine("PrepareCall Failed: [ " + e.Error.Message + " ]");
        }
    }

采纳答案by Marc Gravell

From MSDN:

MSDN

If the operation completes successfully and its result is assigned in the DoWork event handler, you can access the result through the RunWorkerCompletedEventArgs.Result property.

如果操作成功完成并且其结果已在 DoWork 事件处理程序中分配,您可以通过 RunWorkerCompletedEventArgs.Result 属性访问结果。

and:

Your RunWorkerCompleted event handler should always check the Error and Cancelled properties before accessing the Result property. If an exception was raised or if the operation was canceled, accessing the Result property raises an exception.

在访问 Result 属性之前,您的 RunWorkerCompleted 事件处理程序应始终检查 Error 和 Canceled 属性。如果引发异常或取消操作,则访问 Result 属性会引发异常。

So if it doesn'tcomplete successfully (i.e. you cancel it) it looks like it won't work. Perhaps consider returning your cancellation-details as the result (as success) for your abort case, an detecting the difference in the completion handler?

因此,如果它没有成功完成(即您取消它),它看起来将不起作用。也许考虑将您的取消详细信息作为中止情况的结果(作为成功)返回,检测完成处理程序中的差异?

回答by Jon Skeet

The Resultproperty is meant to represent the result of a completedoperation. You've set Cancelto true, meaning that the operation was cancelled, therefore there shouldn't be a result.

Result属性旨在表示已完成操作的结果。您已设置Cancel为 true,这意味着操作已取消,因此不应有结果。

It sounds like you should encode the "I aborted because something was wrong" into your result, or throw an exception which will be set as the Errorproperty in the result instead - Cancelis meant to be set if the worker noticed that the call was cancelled externally.

听起来您应该将“我因为出现问题而中止”编码到您的结果中,或者抛出一个异常,该异常将被设置为Error结果中的属性 -Cancel如果工作人员注意到调用在外部被取消,则应进行设置.

The docs for RunWorkerCompletedEventArgs.Resultstate:

RunWorkerCompletedEventArgs.Result状态文档:

Your RunWorkerCompleted event handler should always check the Error and Cancelled properties before accessing the Result property. If an exception was raised or if the operation was canceled, accessing the Result property raises an exception.

在访问 Result 属性之前,您的 RunWorkerCompleted 事件处理程序应始终检查 Error 和 Canceled 属性。如果引发异常或取消操作,则访问 Result 属性会引发异常。

The "Exceptions" part of the documentation also states that it will throw an exception if Cancelledis true.

文档的“异常”部分还指出,如果Cancelled为真,它将抛出异常。

回答by parapet

It's most probably because the code Cancels the work instead of completing it. So try accessing the result in the if(!e.Cancel) branch.

这很可能是因为代码取消了工作而不是完成它。所以尝试访问 if(!e.Cancel) 分支中的结果。