请问这段C#代码为啥结果是CBA?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请问这段C#代码为啥结果是CBA?相关的知识,希望对你有一定的参考价值。

刚开始学习C#的多线程,为什么这段代码的结果不是ABC而是CBA呢?

参考技术A

你的代码大概率只会显示CAB,而不是CBA,只有当你把Task里面那个sleep写在赋值前面才会CBA,是大概率出现CBA不保准不会CAB。

这个线程你没理解,有很多问题。

    主线程休眠Thread.Sleep。整个线程都会卡 主,你只休眠1秒不明显,改一下,10000这个值试 下,你会发现窗体拖都拖不动。我们再测试深一点,把C赋值休眠改成20秒,上面的改成1秒,你会惊奇的发现还是C在前面。这是为什么呢?代码编译逻辑实际上是先读脚本,从上到下它先读一遍,读到了Thread.Sleep这个不正常的操作,他们没异常,他是让整个主线程冻结CPU先休眠,所以按道理讲他是先执行主线程的,再去理会子线程,这就是为什么你在主线程赋值,子线程调用不及时的原因。所以无论你怎么处理用TASK他是优先处理主线程C的赋值。

    子线程用Invork,这个是针对句柄的,窗体句柄刷新速度是后台刷新的,你控制不了,很有可能系统会蹦出一个错误:从不创建句柄的控件访问线程,它有begininvork和endinvork一说,我们宁愿这样写TB_Log.BeginInvoke(new Action(()=>TB_Log.Text += "A"; ));也比你的写法来得及时,因为你是刷新窗体句柄。而且这个刷新时间是独立无规律的。再说子线程是并行的,子线程运行效率靠系统分配,不可控,你可能看到是BA,也有可能是AB。这里我跟你解释为什么休眠在前面大概率是BA,因为主线程休眠,它的内部过程被挂起,T1,T2进栈堆积,出栈是T2,T1的方式处理,如何让他大概率是AB,我说出来你不要觉得搞笑,public Task  t2,t1;这样处理下,构造函数里面顺序也调一下。我之前是测试过的。

那如何有顺序的执行线程?第一线程传值用SynchronizationContext同步,不用invork刷新,方法的传递用回调,而不是用delegete创建简单的action,当一个线程执行完了我们回调方法去执行下一个,这才是正确的处理方式。

以上是关于请问这段C#代码为啥结果是CBA?的主要内容,如果未能解决你的问题,请参考以下文章

C# 编译器会优化这段代码吗?

C#连接MySQL数据库的问题,主界面调用这个函数,结果返回值是-1,请问为啥会抛出异常呢?应该怎么改呢?

C# 计算程序运行时间

在 c# 代码中,为啥下面的副本不能作为参考副本? [复制]

如何使用 C# 创建一个对象以统一在两个位置之间移动,为啥我的代码不起作用?

为啥我的 C# IS 语句不起作用?