2012-03-08 58 views
5

我有一個小型應用程序需要測試多個連接(每個一次一個地完成)的SQL連接字符串。要做到這一點,我暫時設置ConnectionTimeout = 5以避免連接無效並且等待很長時間(等待一段時間),比如說。TPL如何執行「回撥」

爲了避免UI掛,而我們試圖Open()連接不良(即使ConnectionTimeout = 5等待爲SqlException可以達到二十秒爲單位),我想運行使用任務並行庫一個單獨的線程測試(TPL )。所以我分拆我的新主題,如:

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

的問題是,這仍是鎖定UI(清晰),因爲它是返回給調用者之前等待結果。我如何讓代碼將控制返回給UI(釋放GUI),同時從異步Task獲得最終結果?

另外,從Task內我可以合法地做MessageBox.Show("Some message")?這對BackgroundWorkers不起作用,並且此池線程默認爲後臺線程;但它似乎不成問題。謝謝你的時間。

回答

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。

但是你很長時間延長了任務的壽命,這不是一個好主意。

+0

非常感謝您的回覆。整個想法是儘快回到UI/GUI的控制權,上述是如何實現的?如果我從一個名爲'ParrTestConn(SqlConnection conn,string bShowErrMsg)'的方法調用上述代碼,那麼我不能說'asyncTestConn.ContinueWith(ParrTestConn(conn,bShowErrMsg))'...或者我可以嗎? – MoonKnight 2012-03-08 12:31:55

+0

@Killer你可以簡單地在開始()後返回。在使用這個GUI時,GUI應該保持響應。 – 2012-03-08 12:55:09

+0

我沒有'Task.Factory.Create '方法可用? – MoonKnight 2012-03-08 13:02:13

5

對於TPL,ContinueWith正是你想要的。 Henk的回答:

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

真的很有幫助。謝謝。這兩個答案的組合絕對是薄荷。 – MoonKnight 2012-03-08 14:45:36