6

onCompleteCallBack呼び出されたのと同じスレッドでメソッドを呼び出すにはどうすればよいSomeAsyncMethodですか?

public void SomeAsycMethod ( Action<object> onCompleteCallBack )
{
    // get the current thread 
    /* var ThisThread = Thread.CurrentThread. */

    Task.Factory.StartNew( () =>
    {
        Thread.Sleep( 1000 );// do some work;

        // lastly call the onCompleteCallBack on 'ThisThread'
        onCompleteCallBack( "some result" );

        // I am looking for something like:
        /* ThisThread.Invoke("some result"); */
    });
}
4

2 に答える 2

6

コールバックが同じスレッドで呼び出されることは保証できませんが、同じ同期コンテキストで呼び出されることは保証できます(元の呼び出しに存在すると仮定します)。

public void SomeAsycMethod ( Action<object> onCompleteCallBack )
{
    // get the current context
    var context = SynchronizationContext.Current;

    Task.Factory.StartNew( () =>
    {
        Thread.Sleep( 1000 );// do some work;

        // lastly call the onCompleteCallBack on 'ThisThread'
        onCompleteCallBack( "some result" );

        // I am looking for something like:
        context.Post(s => onCompleteCallBack ("some result"), null); 
    });
}

たとえば、Windows フォームまたは WPF プログラムでは、上記により、(メッセージ ループまたはディスパッチャーを介して) GUI スレッドでコールバックが呼び出されることが保証されます。ASP.NET コンテキストについても同様です。

そうは言っても、私は Justin Harvey に同意しTask<T>ます。

于 2012-11-28T16:31:09.837 に答える
4

実際、タスクベースの非同期プログラミングを使用している場合は、コードをリファクタリングして戻りTask<T>、クライアント自体がコールバック メソッドを呼び出すコンテキストを決定できるようにすることをお勧めします (また、将来の C# 5.0 への移行を容易にします ;):

public Task<string> SomeMethodAsync()
{
   return Task.Factory.StartNew(() => "some result");
}

UI スレッドからこのメソッドを呼び出すことが確実にわかっている場合は、次のように使用できます。

var task = SomeMethodAsync();
task.ContinueWith(t => textBox.Text = t.Result, TaskScheduler.FromSynchronizationContext);

このアプローチは、懸念事項をより明確に分離し、同期コンテキストに依存せずに任意のコンテキストで非同期メソッドを使用できるようにするため、より優れています。一部のクライアントは UI スレッドからこのメソッドを呼び出すことができます (この場合TaskScheduler.FromSynchronizationContext、期待どおりに動作します - 「継続」は UI スレッドで呼び出されます)。一部のクライアントは、処理などの要件なしで非 UI スレッドからもメソッドを使用できます。非同期操作を開始する同じスレッドになります。

Task<T>は、より宣言的なコードを取得するだけでなく、より明確で読みやすく、テストしやすいファースト クラス オブジェクトとして非同期操作を表す完璧なクラスです(このメソッドを簡単にモックして、「偽の」タスク オブジェクトを返すことができます)。

于 2012-11-28T18:18:52.287 に答える