延迟继续不工作

E_N*_*N_Y 5 c# multithreading async-await

我的问题是为什么延迟方法不起作用(整个操作不等待4秒)并且60%没有显示在lable1内部.

更准确地说,操作的顺序应该是这样的,整个操作应该花费8秒.但是它需要4秒,就Thread.Sleep(4000)在里面LongTimeMethod1()工作正常

LongTimeMethod1()//delay for 4 sec,show 60%
delay()//delay for 4 sec 
LongTimeMethod()//40% imidiatly
Run Code Online (Sandbox Code Playgroud)

我知道我可以用await和async编写代码,但我想知道我在这段代码中做错了什么.

 private void button1_Click(object sender, EventArgs e)
    {
        CallBigMethod();
        label1.Text =@"Waiting ...";
    }
    private async void CallBigMethod()
    {
        var result = await BigMethod();
        label1.Text = result; 


    }
    private Task<string> BigMethod()
    {
        return Task.Factory
         .StartNew(() => LongTimeMethod1())
         .ContinueWith((pre) => Delay())
         .ContinueWith((pre) => LongTimeMethod());
    }     
    private string LongTimeMethod()
    {

        return  "40%...";
    }
    public async Task Delay()
    {

        await Task.Delay(4000);

    }
    private string LongTimeMethod1()
    {
        Thread.Sleep(4000);
        return "60%...";
    }  
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 8

Task返回的.ContinueWith((pre) => Delay())实际上是一个为Task<Task>.这延续将尽快完成它完成启动延迟,但由于延迟是异步的,它不会等待它完成.你需要打开它,Task<Task>以便你在内部任务中添加一个延续,并让你的程序在延迟结束时继续,而不是在它完成启动时.

幸运的是,有一种Unwrap方法可以为我们完成所有这些.

private Task<string> BigMethod()
{
    return Task.Factory
     .StartNew(() => LongTimeMethod1())
     .ContinueWith((pre) => Delay())
     .Unwrap()
     .ContinueWith((pre) => LongTimeMethod());
}    
Run Code Online (Sandbox Code Playgroud)

也就是说,当方法是async,而不是使用时,整个事情要简单得多ContinueWith:

private Task<string> BigMethod()
{
    await Task.Run(() => LongTimeMethod1());
    await Delay();
    return await Task.Run(() => LongTimeMethod());
} 
Run Code Online (Sandbox Code Playgroud)


Bob*_*obi 0

尝试这个

private Task<string> BigMethod()
    {

        return Task.Factory.StartNew(() => LongTimeMethod1()).ContinueWith(async (pre) => await Delay()).ContinueWith((pre) => LongTimeMethod());
    }
Run Code Online (Sandbox Code Playgroud)