TPL How to make a "call back"

I have a small application that needs to check SQL connection strings for multiple connections (each of them runs once in a while). For this, I temporarily set ConnectionTimeout = 5it to avoid a long wait if the connection is invalid and ConnectionTimeout = 0(wait forever), say.

To prevent the user interface from freezing when trying Open()to connect poorly (even if it can ConnectionTimeout = 5wait SqlExceptionup to twenty seconds), I want to run the test in a separate thread using the Parallel Library Task (TPL). Therefore, I highlight my new thread, for example:

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

The problem is that this still blocks the user interface (explicitly), as it waits for the result before returning to the caller. How to allow code to return control to the user interface (freeing the GUI), getting the final result from asynchronous Task?

Also, Taskcan I legitimately do from the inside out MessageBox.Show("Some message")? This does not work for BackgroundWorkers, and this pool thread is the default background thread; but it doesn't seem to be a problem. Thank you for your time.

+5
source share
2 answers

You are right, there is an expectation:

 return asyncTestConn.Result;

You can simply create the termination code in the tail of TestConnection () or use Continuation:

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

Can I legally do MessageBox.Show("Some message")?

, MessageBox . Bgw.

, .

+4

TPL ContinueWith - , . :

var asyncTestConn = Task.Factory.StartNew(() => TestConnection(conn, bShowErrMsg));
// Henk "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());
+5

All Articles