TPL

2012-03-08 5 views
5

私は、接続の数(それぞれが1つずつ行われる)のためのSQL接続文字列をテストする必要がある小さなアプリケーションを持っています。これを行うには、接続が有効でなく、ConnectionTimeout = 0(永遠に待機する)と言うと、長い待ち時間を避けるためにConnectionTimeout = 5を一時的に設定します。我々はOpen()に接続不良を(たとえConnectionTimeout = 5SqlExceptionための待ち時間が20秒まで可能)しようとしながら、ぶら下がっUIを避けるためにTPL

、私はタスク並列ライブラリ(TPLを使用して別のスレッドでテストを実行したいです)。だから私はスピンオフのように私の新しいスレッド:

Task<bool> asyncTestConn = Task.Factory.StartNew<bool> 
    (() => TestConnection(conn, bShowErrMsg)); 
return asyncTestConn.Result; 

問題は、それは、呼び出し元に戻る前に、結果を待っているようこれはまだ、(明らかに)UIをロックしていることです。非同期Taskからの最終結果を取得しながら、コードがUIに制御を戻す(GUIを解放する)ようにするにはどうすればよいですか?

また、Task内から、私は正当にMessageBox.Show("Some message")を行うことができますか?これはBackgroundWorkersでは機能せず、このpooled-threadはデフォルトでバックグラウンドスレッドです。それでも問題はないようです。御時間ありがとうございます。待機が発生した場所

答えて

4

あなたが正しい、これは次のとおりです。

return asyncTestConn.Result; 

あなたは単にTestConnection(の尾で仕上げアップコードをビルド)または継続を使用することができます。

// untested 
//Task<bool> asyncTestConn = Task.Factory.Create<bool> (
Task<bool> asyncTestConn = new Task<bool> (
    () => TestConnection(conn, bShowErrMsg)); 
asyncTestConn.ContinueWith(MyFinishCode); 
asyncTestConn.Start() 

私は正当にMessageBox.Show("Some message")を行うことができますか?

実際、はい、MessageBoxはスレッドセーフです。 Bgwからも可能でなければならない。あなたはたくさんのことで、タスクの寿命を延ばすいる

しかし、それは良い考えではありません。 TPLのために

+0

お返事ありがとうございました。全体のアイデアは、できるだけ早くUI/GUIに戻って制御を戻すことです、どのように/上記の達成することができますか?上記のコードを 'ParrTestConn(SqlConnection conn、string bShowErrMsg)'メソッドから呼び出すと、 'asyncTestConn.ContinueWith(ParrTestConn(conn、bShowErrMsg)) 'と言うことはできません。 – MoonKnight

+0

@Killer Start()の後に戻ります。これを使用するとき、GUIは反応し続ける必要があります。 –

+0

'Task.Factory.Create 'メソッドは使用できません。 – MoonKnight

5

ContinueWithは正確に何をしたいです。ヘンクの答えで拡大:

var asyncTestConn = Task.Factory.StartNew(() => TestConnection(conn, bShowErrMsg)); 
// Henk's "MyFinishCode" takes a parameter representing the completed 
// or faulted connection-testing task. 
// Anything that depended on your "return asyncTestConn.Result;" statement 
// needs to move into the callback method. 
asyncTestConn.ContinueWith(task => 
    { 
     switch (task.Status) 
     { 
      // Handle any exceptions to prevent UnobservedTaskException. 
      case TaskStatus.Faulted: /* Error-handling logic */ break; 
      case TaskStatus.RanToCompletion: /* Use task.Result here */ break; 
     } 
    }, 
    // Using this TaskScheduler schedules the callback to run on the UI thread. 
    TaskScheduler.FromCurrentSynchronizationContext()); 
+0

本当に有益です。ありがとう。 2つの答えの組み合わせは絶対にミントです。 – MoonKnight