3

私は次のコードを持っています:

void ReferenceManager_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {

        // Get the raw data
        byte[] data = this.GetData(IvdSession.Instance.Company.Description, IvdSession.Instance.Company.Password);

        // Deserialize the list
        List<T> deseriaizedList = null;
        using (MemoryStream ms = new MemoryStream(data))
        {
            deseriaizedList = Serializer.Deserialize<List<T>>(ms);
        }

        // Convert the list to the Reference Interface
        List<IReference> referenceList = new List<IReference>();
        foreach (T entity in deseriaizedList)
        {
            IReference reference = (IReference)entity;
            referenceList.Add(reference);
        }

        e.Result = referenceList;

    }
    catch (WebException)
    {
        e.Result = null;
    }
}

このコードは基本的に、WebService メソッドへのデリゲートを呼び出しています。残念ながら、バックグラウンド ワーカーを使用した主な理由は、データの読み込み時に UI がフリーズするのを防ぐことでした。「お待ちください。キャンセルするにはここをクリックしてください」というポップアップ フォームがあります。

キャンセルをクリックすると、バックグラウンド ワーカーで CancelAsync を呼び出します。今、私はループしていないので、キャンセルを確認する良い方法がわかりません。私が見ることができる唯一のオプションは...

byte[] m_CurrentData;

...メソッドの外側で、Web サービスを呼び出して m_CurrentData を設定する DoWork(..) の開始時に新しいスレッドを起動します。次に、キャンセルされたかどうかをチェックするループを実行するか、m_CurrentData が null ではないかどうかをチェックする必要があります。

キャンセルを達成するためのより良い方法はありますか?

4

2 に答える 2

3

実際の作業は、表示されてthis.GetData(...)いないメソッド内で行われるようです。私はそれがWebサービスを呼び出していると収集します。Abort()クライアントが応答を待機しないようにするには、おそらくプロキシ オブジェクトでメソッドを呼び出す必要があります。を呼び出しても意味がありません。CancelAsync()エラーを正しくチェックするようにしてくださいRunWorkerCompleted()。最も簡単な方法は、おそらく で例外をキャッチせず_DoWork()、 で Result.Error プロパティをチェックすることですCompleted()。とにかくそうするべきです。

明確にするために、CancelAsync() メソッドは DoWork() 内のループを停止する場合にのみ役立ちます。そこでは (意味のある) ループを実行していないため、別のアプローチが必要です。

于 2009-06-09T19:46:52.627 に答える
1

アップデート

MSDN をDoWorkEventArgs確認したところ、以前の回答が間違っていたことに気付きました。(MSDNから)への呼び出しによって設定されるCancellationPendingプロパティがあります。したがって、メソッドは次のようになります。BackgroundWorkerCancelAsyncDoWork

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // Do not access the form's BackgroundWorker reference directly.
    // Instead, use the reference provided by the sender parameter.
    BackgroundWorker bw = sender as BackgroundWorker;

    // Extract the argument.
    int arg = (int)e.Argument;

    // Start the time-consuming operation.
    e.Result = TimeConsumingOperation(bw, arg);

    // If the operation was canceled by the user, 
    // set the DoWorkEventArgs.Cancel property to true.
    if (bw.CancellationPending)
    {
        e.Cancel = true;
    }
}

これ使えますか?

于 2009-06-09T19:34:17.787 に答える