所以我有类似的代码
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
不起作用:
呼叫线程无法访问此对象,因为不同 线程拥有它
我该如何解决?也许我应该完全使用另一种方法来实施我想要的东西。谢谢。
您需要此:
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();
}
首先,您必须启动任务才能等待它;)
如果要使用continewith()而不是异步/等待,则可以使用选项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
尝试执行此操作,对我有用:
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;