TPL如何进行'回叫'

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,默认情况下,此池化线程是后台线程; 但它似乎不是一个问题.谢谢你的时间.

sha*_*tor 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());
Run Code Online (Sandbox Code Playgroud)


Hen*_*man 4

你是对的,这就是等待发生的地方:

 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 也应该可以。

但是你大大延长了任务的寿命,这不是一个好主意。