Reputation: 329
So I have code something like that
private void doSmth()
{
str = makeStr();
}
private void button_Click(object sender, EventArgs e)
{
Task task = new Task(doSmth);
task.Start();
task.Wait();
textBox.Text = str;
}
It's freezing and I know why this is happening because of Wait()
. I was trying to use ContinueWith()
like this
task.ContinueWith((t) => {textBox.Text = str;});
But it doesn't work throwing an InvalidOperationException
:
The calling thread cannot access this object because a different thread owns it
How can I fix this? Maybe I should use completely another approaches to implement what I want to. Thanks.
Upvotes: 1
Views: 3317
Reputation: 367
Try do this, it works for me :
Task ts =new Task(new Action(()=>{
//your code here
}
));
ts.Start();//start task
//here we wait until task completed
while (!ts.IsComplete)//check until task is finished
{
//pervent UI freeze
Application.DoEvents();
}
//Task Completed
//Continue with ...
textBox.Text = ts.Result;
Upvotes: 0
Reputation: 164
Well first of all you have to start the task to be able to wait for it ;)
If you want to use ContinueWith() rather than async/await, you just can use the option TaskContinuationOptions.ExecuteSynchronously
. This will cause the continuation operation to be executed in the calling thread.
Task task = new Task(doSmth);
task.ContinueWith(t => textBox.Text = str, TaskContinuationOptions.ExecuteSynchronously);
task.Start();
//task.Wait(); // optional if you want to wait for the result
Upvotes: 0
Reputation: 155145
You'll want this:
private String DoSomething() {
return makeStr(); // return it, don't set it to a field.
}
private async void button_Click(...) {
String result = await Task.Run( DoSomething );
textBox.Text = result;
}
...which is equivalent to this:
private async void button_Click(...) {
// Task<> is the .NET term for the computer-science concept of a "promise": https://en.wikipedia.org/wiki/Futures_and_promises
Task<String> resultPromise = Task.Run( DoSomething );
String result = await resultPromise;
textBox.Text = result;
}
...which is (roughly) equivalent to this:
private void button_Click(...) {
Thread thread = new Thread( () => {
String result = DoSomething();
this.BeginInvoke( () => {
this.textBox.Text = result;
} );
} );
thread.Start();
}
Upvotes: 7