简体   繁体   中英

First experiment calling asynch method - Do I need ALL this code?

Never tried asynch calling with Windows Form. I cannot use the new aynch/await because I don't own recent Visual Studio/.NET. What I need is "execute an operation that request long time (populate an IList)" and, when it has finished, write on a TextBox the result of that list.

Searching on Internet I found this example that seems work, but TOO comply in my opinion (maybe there are somethings fast and simple):

private void button1_Click(object sender, EventArgs e)
{
    MyTaskAsync();
}

private void MyTaskWorker()
{
    // here I populate the list. I emulate this with a sleep of 3 seconds
    Thread.Sleep(3000);
}

private delegate void MyTaskWorkerDelegate();

public void MyTaskAsync()
{
    MyTaskWorkerDelegate worker = new MyTaskWorkerDelegate(MyTaskWorker);
    AsyncCallback completedCallback = new AsyncCallback(MyTaskCompletedCallback);

    AsyncOperation async = AsyncOperationManager.CreateOperation(null);
    worker.BeginInvoke(completedCallback, async);
}

private void MyTaskCompletedCallback(IAsyncResult ar)
{
    MyTaskWorkerDelegate worker = (MyTaskWorkerDelegate)((AsyncResult)ar).AsyncDelegate;
    AsyncOperation async = (AsyncOperation)ar.AsyncState;

    worker.EndInvoke(ar);

    AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null, false, null);
    async.PostOperationCompleted(delegate(object e) { OnMyTaskCompleted((AsyncCompletedEventArgs)e); }, completedArgs);
}

public event AsyncCompletedEventHandler MyTaskCompleted;

protected virtual void OnMyTaskCompleted(AsyncCompletedEventArgs e)
{
    if (MyTaskCompleted != null)
        MyTaskCompleted(this, e);

    // here I'll populate the textbox
    textBox1.Text = "... content of the Iteration on the List...";
}

really I NEED somethings like 50 lines of code for this easy operation? Or I can remove some stuff? I just need a simple asynch call->callback when finished.

No lock, no concurrency at all...

You can use the TPL with C# 4.0 like so:

private void button1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() => DoWork())
        .ContinueWith(t => UpdateUIWithResults(t.Result)
        , CancellationToken.None
        , TaskContinuationOptions.None
        , TaskScheduler.FromCurrentSynchronizationContext());
}

This starts DoWork in a thread pool thread, allowing it to do processing out of the UI thread, then runs UpdateUIWithResults in a UI thread, passing it the results of DoWork .

You can use Task.Factory.StartNew to push work onto the thread pool. Task.ContinueWith will give you a "completed callback".

private void button1_Click(object sender, EventArgs e)
{
    var ui = TaskScheduler.FromCurrentSynchronizationContext();
    Task<List<T>> task = Task.Factory.StartNew(() => MyTaskWorker());
    task.ContinueWith(t => OnMyTaskCompleted(t), ui);
}

private List<T> MyTaskWorker()
{
    // here I populate the list. I emulate this with a sleep of 3 seconds
    Thread.Sleep(3000);
    return ...;
}

protected virtual void OnMyTaskCompleted(Task t)
{
    // here I'll populate the textbox with t.Result
    textBox1.Text = "... content of the Iteration on the List...";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM