如何使用Task.Wait避免WinForm冻结

Den*_*lik 1 c# multithreading task winforms

所以我有类似的代码

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;
}
Run Code Online (Sandbox Code Playgroud)

它很冷,我知道为什么会这样,因为Wait().我试图用ContinueWith()这样

task.ContinueWith((t) => {textBox.Text = str;});
Run Code Online (Sandbox Code Playgroud)

但它不起作用InvalidOperationException:

调用线程无法访问此对象,因为另一个线程拥有它

我怎样才能解决这个问题?也许我应该完全使用另一种方法来实现我想要的东西.谢谢.

Dai*_*Dai 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;
}
Run Code Online (Sandbox Code Playgroud)

......这相当于:

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;
}
Run Code Online (Sandbox Code Playgroud)

...(大致)相当于此:

private void button_Click(...) {

    Thread thread = new Thread( () => {

        String result = DoSomething();
        this.BeginInvoke( () => {

            this.textBox.Text = result;
        } );

    } );
    thread.Start();
}
Run Code Online (Sandbox Code Playgroud)