Reputation: 47995
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...
Upvotes: 1
Views: 150
Reputation: 456887
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...";
}
Upvotes: 0
Reputation: 203827
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
.
Upvotes: 2