17

C# 2008 SP1

バックグラウンドワーカーを使用しています

条件の 1 つが失敗した場合、e.cancel を true に設定し、文字列を e.result に割り当てます。すべてがそこで機能します。

ただし、workCompleted が起動すると、e.Result をテストすると、「e.result は systeminvalidoperation 型の例外をスローします」という例外が発生します。

グローバル変数を使用して DoWork に設定し、完了した作業を比較できると思います。しかし、これはスレッドセーフではないかもしれません。

e.Resultでこれを取得する理由と、これを解決するにはどうすればよいですか?

どうもありがとう、

    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 + " ]");
        }
    }
4

3 に答える 3

27

MSDNから:

操作が正常に完了し、その結果が DoWork イベント ハンドラーに割り当てられている場合は、RunWorkerCompletedEventArgs.Result プロパティを介して結果にアクセスできます。

:

RunWorkerCompleted イベント ハンドラーは、Result プロパティにアクセスする前に、常に Error プロパティと Canceled プロパティをチェックする必要があります。例外が発生した場合、または操作がキャンセルされた場合、Result プロパティにアクセスすると例外が発生します。

したがって、正常に完了しない場合(つまり、キャンセルした場合) は機能しないように見えます。おそらく、中止の場合の結果として (成功として) キャンセルの詳細を返し、完了ハンドラーの違いを検出することを検討してください。

于 2009-05-13T06:13:51.207 に答える
19

プロパティは、完了しResultた操作の結果を表すことを目的としています。true に設定しました。これは、操作がキャンセルされたことを意味するため、結果はありません。Cancel

「何かが間違っていたため中止しました」を結果にエンコードするか、Error代わりに結果のプロパティとして設定される例外をスローする必要があるようです-Cancelワーカーが呼び出しが外部でキャンセルされたことに気付いた場合に設定することを意図しています.

状態のドキュメントRunWorkerCompletedEventArgs.Result:

RunWorkerCompleted イベント ハンドラーは、Result プロパティにアクセスする前に、常に Error プロパティと Canceled プロパティをチェックする必要があります。例外が発生した場合、または操作がキャンセルされた場合、Result プロパティにアクセスすると例外が発生します。

ドキュメントの「例外」の部分には、 true の場合に例外がスローされることも記載されていCancelledます。

于 2009-05-13T06:11:00.197 に答える
2

おそらく、コードが作業を完了するのではなくキャンセルするためです。そのため、if(!e.Cancel) ブランチで結果にアクセスしてみてください。

于 2009-05-13T06:21:06.513 に答える