2017-10-20 14 views
-2

実際のsyncメソッドでクラスライブラリを作成したかったので、同期コードを実行するのにTask.Runを使用する偽の非同期メソッドを実装しないようにしました。真に非同期メソッドを実装する方法は?

私は1つの方法は、このようにしていることを見てきた:

public Task miMethodAsync() 
{ 
    TaskCompletionSource<bool> miTcs = new TaskCompletionSource<bool>(); 
    new Timer(_ => 
     { 
      for (Int64 i = 1; i < 10000000; i++) 
      { 
       //todo my long code 
      } 
      miTcs.SetResult(true); 
     }) 
     .Change(0, Timeout.Infinite); 

    return miTcs.Task; 
} 

このソリューションは、その後は0msに後で、それはタイマー内のコードを実行されます、タスクを返すためにタイマーを使用しています。

このソリューションは新しいタスクを作成しないため、スレッドフォームのスレッドプールを使用しないため、拡張性が良好です。しかし、私は、このソリューションは、同期コードを実行するためにタイマーを使用して、それはエレガントなソリューションではないと思うので、本当に私は本当に非同期メソッドを実装することができますか?

も、私は私の同期方法を持っている可能性があり、ちょうどこのようにASYNメソッドを実装し、このソリューションので:

public Task myMethodAsync() 
{ 
    TaskCompletionSource<bool> miTcs = new TaskCompletionSource<bool>(); 
    new Timer(_ => 
     { 
      myMethodSync(); 
      miTcs.SetResult(true); 
     }) 
     .Change(0, Timeout.Infinite); 

    return miTcs.Task; 
} 

しかし、私はコメントとして、私はそれはエレガントな解決策ではないと思うが、実際にそれがいるようですTask.Run()メソッド内で同期コードを実行するときのような偽の非同期メソッドではありません。

+0

タイマーコードが同じスレッド(これはUIスレッド)で実行され、長時間実行されている場合でもUIはフリーズします。もし、しかし、タイマーは新しいスレッドを作成し、タイマーでこれを隠すことで何を獲得していますか? –

+3

これは、同期メソッドが実行されている間だけスレッドを使い果たします。それがアクティブスレッド、UIスレッド、またはスレッドプールスレッドのいずれであるかは、あなたが使用している.NETライブラリの 'Timer'という名前の6つのクラスと、' myMethodAsync() 'を呼び出すスレッドによって異なります。 –

+1

同期コードに対して 'async'ラッパーを作ろうとする理由を詳しく説明できますか?引用した記事[最後の質問から]を読んでいると仮定します(https://stackoverflow.com/questions/46845005/is-it-really-a-bad-ide-to-use-threads-in-a-class-library )あなたはそれが悪い考えであることを知っています。あなたは 'タスク'返すインターフェイスを果たしていますか?もしそうなら、 'Task.FromResult'か' Task.CompletedTask'のいずれかを返し、クライアントがいつプロセスをオフロードするかを決定させます。それ以上の詳細がなければ、前回のアドバイス、[** do not do ** **](https://stackoverflow.com/a/32642687/7339946)の引用があります。 – JSteward

答えて

1

同期コードを擬似asyncメソッドにラップするこれらのラッパーは何も役に立ちません。推奨される方法は、そのようなラッパーを作成するのではなく、むしろAPIユーザーがTask.Run(SyncMethod)自体を行うようにすることです。

詳しくはarticleをご覧ください。

関連する問題