Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

However, when the workCompleted fires, I test for the e.Result and I get an exception "e.result throw an exception of type 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.

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

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 + " ]");
        }
    }
like image 498
ant2009 Avatar asked May 13 '09 06:05

ant2009


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Is C programming hard?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.


2 Answers

From 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.

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.

So if it doesn't complete 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?

like image 121
Marc Gravell Avatar answered Sep 28 '22 07:09

Marc Gravell


The Result property is meant to represent the result of a completed operation. You've set Cancel to true, meaning that the operation was cancelled, therefore there shouldn't be a result.

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 Error property in the result instead - Cancel is meant to be set if the worker noticed that the call was cancelled externally.

The docs for RunWorkerCompletedEventArgs.Result state:

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.

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

like image 33
Jon Skeet Avatar answered Sep 28 '22 08:09

Jon Skeet