值后异步方法的简历没有更新 [英] Value is not updating after async method resume

查看:85
本文介绍了值后异步方法的简历没有更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看着这个code:

public class SharedData
{
    public int Value { get; set; }
}

void button1_Click(object sender, EventArgs e)
{
    AAA();
}

async Task BBB(SharedData data)
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    MessageBox.Show(data.Value.ToString()); //<---- I always see 0 here,
    data.Value = data.Value + 1;
}

async Task<int> AAA()
{
    SharedData data = new SharedData();
    var task1 = BBB(data);
    var task2 = BBB(data);
    var task3 = BBB(data);

    await Task.WhenAll(task1, task2, task3);
    MessageBox.Show(data.Value.ToString());  //<--- this does show 3
    return data.Value;
}

这是一个GUI(视窗形式)的应用,这意味着只有一个线程中执行的code各自行

This is a GUI (windows forms ) application , which means that there is only one thread executing each line of code.

所有 BBB(数据)调用调用非常快,无需等待。 每个 BBB 调用获得的进入BBB 方法,见等待不完成并返回(至AAA)。

All BBB(data) invocations are invoked very quick without waiting. Each BBB invocation get's into the BBB method , sees await which doesn't complete and returns ( to AAA).

现在,当一个秒(约)过去后,所有的延续正在发生的在GUI线程的。

Now , when one second (approx) is elapsed, all continuations are happening in the GUI thread.

问题

延续不会同时发生,因为它是一个GUI线程。 因此,一个previous语句:

Continuations doesn't happen simultaneously because it's a GUI thread . So a previous statement of :

data.Value = data.Value + 1;

必须发生。

在换句话说,

我知道,所有的 BBB ,则与数据相同的初始值调用,但延续没有按'牛逼同时发生

I know that all BBBs are invoked with the same initial value of data , but the continuations doesn't happens concurrently

GUI线程必须运行最后:

The GUI thread must run eventually:

<子>延续#1

 MessageBox.Show(data.Value.ToString()); 
 data.Value = data.Value + 1; //So this basically should do 0-->1
....

<子>延续#2

 MessageBox.Show(data.Value.ToString()); // Why data.Value still "0" ??
 data.Value = data.Value + 1;  
....

<子>延续#3

 MessageBox.Show(data.Value.ToString()); // Why data.Value still "0" ??
 data.Value = data.Value + 1;

它看起来像延续计划不是作为一个整体,但作为共享量子?

It looks like the continuations are scheduled not as a whole but as shared quanta ?

推荐答案

这是因为你使用的MessageBox.show 的调试输出和显示模式消息框块在code-流,但不会阻止UI线程(否则你无法与消息框交互)。

That happens because you're using MessageBox.Show for debug prints and showing a modal message box blocks the code-flow but doesn't block the UI thread (otherwise you couldn't interact with the message box).

因此​​,当第一连续被封锁通过显示消息框的下继续运行,然后在第三。他们都是封锁通过显示消息框,但用户界面线程本身是没有的。

So, when the first continuation is "blocked" by showing a message box the next continuation can run and then the third. They are all "blocked" by showing the message boxes but the UI thread itself isn't.

这就是为什么他们各显其能 0 只有当你释放消息框,它们可以继续运行,并增加了变量。

That's why they all show 0 and only when you release the message boxes they can continue running and increase the variable.

您可以看到,如果您使用打印值 Console.WriteLine 显示消息框前:

You can see that if you print the value using Console.WriteLine before showing the message box:

async Task BBB(SharedData data)
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    Console.WriteLine(data.Value);
    MessageBox.Show(data.Value.ToString());
    data.Value = data.Value + 1;
}

您会注意到 0 打印3次1秒后完全所有的延续,而不是在您关闭该消息框。

You'll notice that 0 is printed 3 times by all the continuations exactly after 1 second and not after you dismiss the message boxes.

基本上,的延续平行并发运行,但没有使用相同的线程因为的MessageBox.show 在其中。

如果您使用 Console.WriteLine ,而不是的MessageBox.show 中,您将看到该值在加一时间:

If you use Console.WriteLine instead of MessageBox.Show you will see that the value is incremented one at a time:

async Task BBB(SharedData data)
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    Console.WriteLine(data.Value);
    data.Value = data.Value + 1;
}

输出:

0
1
2

这篇关于值后异步方法的简历没有更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆