所以我有类似的代码
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;
}
它很冷,我知道为什么会因为Wait()
而发生这种情况。我试图像这样使用ContinueWith()
task.ContinueWith((t) => {textBox.Text = str;});
但抛出InvalidOperationException
:
调用线程无法访问此对象,因为它不同 线程拥有它
我该如何解决这个问题?也许我应该完全使用另一种方法来实现我想要的东西。感谢。
答案 0 :(得分:7)
你会想要这个:
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;
}
......这相当于:
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;
}
...(大致)相当于:
private void button_Click(...) {
Thread thread = new Thread( () => {
String result = DoSomething();
this.BeginInvoke( () => {
this.textBox.Text = result;
} );
} );
thread.Start();
}
答案 1 :(得分:0)
首先,你必须开始任务才能等待它;)
如果要使用ContinueWith()而不是async / await,则可以使用选项TaskContinuationOptions.ExecuteSynchronously
。这将导致在调用线程中执行继续操作。
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
答案 2 :(得分:0)
尝试执行此操作,它对我有用:
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;