Moo*_*ght 5 c# multithreading callback task-parallel-library
我有一个小应用程序,需要测试多个连接的SQL连接字符串(每个连接一次完成).要做到这一点,我ConnectionTimeout = 5暂时设置为避免漫长的等待,如果连接无效和ConnectionTimeout = 0(等待永远),比如说.
为了避免在我们尝试Open()连接错误时挂起UI (即使ConnectionTimeout = 5等待时间SqlException可能长达20秒),我想使用任务并行库(TPL)在单独的线程上运行测试.所以我剥离了我的新线程,如:
Task<bool> asyncTestConn = Task.Factory.StartNew<bool>
(() => TestConnection(conn, bShowErrMsg));
return asyncTestConn.Result;
Run Code Online (Sandbox Code Playgroud)
问题是这仍然是锁定UI(显然),因为它在返回调用者之前等待结果.如何让代码返回控制到UI(腾出GUI),而从异步获取最终的结果Task?
另外,Task我可以从合法的范围内做到MessageBox.Show("Some message")吗?这不起作用BackgroundWorkers,默认情况下,此池化线程是后台线程; 但它似乎不是一个问题.谢谢你的时间.
对于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());
Run Code Online (Sandbox Code Playgroud)
你是对的,这就是等待发生的地方:
return asyncTestConn.Result;
Run Code Online (Sandbox Code Playgroud)
您可以简单地在 TestConnection() 的尾部构建完成代码或使用 Continuation:
// untested
//Task<bool> asyncTestConn = Task.Factory.Create<bool> (
Task<bool> asyncTestConn = new Task<bool> (
() => TestConnection(conn, bShowErrMsg));
asyncTestConn.ContinueWith(MyFinishCode);
asyncTestConn.Start()
Run Code Online (Sandbox Code Playgroud)
我可以合法地做
MessageBox.Show("Some message")吗?
其实是的,MessageBox是线程安全的。Bgw 也应该可以。
但是你大大延长了任务的寿命,这不是一个好主意。
| 归档时间: |
|
| 查看次数: |
3351 次 |
| 最近记录: |