1

Windows フォームで非同期呼び出しを試したことはありません。aynch/await最近の Visual Studio/.NET を所有していないため、新しいものを使用できません。私が必要としているのは、「長い時間を要求する操作を実行する (IList を作成する)」ことであり、それが終了したら、そのリストの結果を TextBox に書き込みます。

インターネットで検索すると、うまくいくように見えるこの例が見つかりましたが、私の意見ではあまりにも準拠しています(おそらく、速くて簡単なものがあるかもしれません):

private void button1_Click(object sender, EventArgs e)
{
    MyTaskAsync();
}

private void MyTaskWorker()
{
    // here I populate the list. I emulate this with a sleep of 3 seconds
    Thread.Sleep(3000);
}

private delegate void MyTaskWorkerDelegate();

public void MyTaskAsync()
{
    MyTaskWorkerDelegate worker = new MyTaskWorkerDelegate(MyTaskWorker);
    AsyncCallback completedCallback = new AsyncCallback(MyTaskCompletedCallback);

    AsyncOperation async = AsyncOperationManager.CreateOperation(null);
    worker.BeginInvoke(completedCallback, async);
}

private void MyTaskCompletedCallback(IAsyncResult ar)
{
    MyTaskWorkerDelegate worker = (MyTaskWorkerDelegate)((AsyncResult)ar).AsyncDelegate;
    AsyncOperation async = (AsyncOperation)ar.AsyncState;

    worker.EndInvoke(ar);

    AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null, false, null);
    async.PostOperationCompleted(delegate(object e) { OnMyTaskCompleted((AsyncCompletedEventArgs)e); }, completedArgs);
}

public event AsyncCompletedEventHandler MyTaskCompleted;

protected virtual void OnMyTaskCompleted(AsyncCompletedEventArgs e)
{
    if (MyTaskCompleted != null)
        MyTaskCompleted(this, e);

    // here I'll populate the textbox
    textBox1.Text = "... content of the Iteration on the List...";
}

この簡単な操作には、本当に 50 行のコードが必要ですか? または、いくつかのものを削除できますか?完了したら、単純な非同期呼び出し->コールバックが必要です。

ロックなし、並行性なし...

4

2 に答える 2

2

次のように C# 4.0 で TPL を使用できます。

private void button1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() => DoWork())
        .ContinueWith(t => UpdateUIWithResults(t.Result)
        , CancellationToken.None
        , TaskContinuationOptions.None
        , TaskScheduler.FromCurrentSynchronizationContext());
}

これはDoWorkスレッド プール スレッドで開始され、UI スレッドから処理を実行できるようになり、次に UI スレッドで実行UpdateUIWithResultsされ、DoWork.

于 2013-04-17T15:41:12.637 に答える
0

Task.Factory.StartNewスレッドプールに作業をプッシュするために使用できます。Task.ContinueWith「完了したコールバック」が表示されます。

private void button1_Click(object sender, EventArgs e)
{
    var ui = TaskScheduler.FromCurrentSynchronizationContext();
    Task<List<T>> task = Task.Factory.StartNew(() => MyTaskWorker());
    task.ContinueWith(t => OnMyTaskCompleted(t), ui);
}

private List<T> MyTaskWorker()
{
    // here I populate the list. I emulate this with a sleep of 3 seconds
    Thread.Sleep(3000);
    return ...;
}

protected virtual void OnMyTaskCompleted(Task t)
{
    // here I'll populate the textbox with t.Result
    textBox1.Text = "... content of the Iteration on the List...";
}
于 2013-04-17T15:40:31.687 に答える