方法调用语句是按照它们的写入顺序同步执行的吗?
例如:
void Function1() { Function2(); Function3(); }
是否可以保证Function3
等到Function2
完成处理每次调用Function1
?
是。 Function3()
等待直到除非Function2()
执行完成。
如果要独立调用它们,可以使用Multi-Threading
概念。
编辑:正如使用Task
评论中建议的要好得多,因为它是一个higher level
概念。
任务与线程
试试这个以独立方式调用它们:
using System.Threading.Tasks; static void Main(String[] args) { Task t1 = new Task(Function2); Task t2 = new Task(Function3); t1.Start(); t2.Start(); }
在这里,我们无法保证执行流程如何继续。因为它们独立运行。
对我来说,“完成处理”是什么意思并不完全清楚。
但Function3()
只有在Function2()
返回后才会被调用,这就是命令式编程背后的全部理念,而基本的C#是一种命令式语言。
严格来说没有。 现代CPU为了提高性能,在引擎盖下进行了大量的优化。 它们并行执行事物,利用分支预测,流水线等,以便它们实际上可以启动甚至完成应该在尚未实际完成的操作之后发生的操作。
但是 ,您不必担心这一点。 我们非常痛苦地隐藏这些实现细节。 虽然这些操作可能实际上并不按给定的顺序进行, 但您不可能观察到它们出现故障的事实 。 换句话说,您可以始终确保执行该代码后计算机的结果状态将是按顺序执行语句时的结果。 如果处理器选择不按顺序执行它们,它将永远不会导致程序的function不同。
当然,正如评论中所述,这仅适用于单个线程的执行。 当您执行多个线程时,对于观察到的每个操作的执行顺序几乎没有保证。
C#语言规范说:
3.10执行顺序
执行C#程序,使得每个执行线程的副作用在关键执行点处得以保留。 副作用定义为易失性字段的读取或写入,对非易失性变量的写入,对外部资源的写入以及抛出exception。 必须保留这些副作用的顺序的关键执行点是对volatile字段(第10.5.3节),锁定语句(第8.12节)以及线程创建和终止的引用。 执行环境可以自由更改C#程序的执行顺序,但受以下限制:
- 数据依赖性保留在执行的线程中。 也就是说,计算每个变量的值,就好像线程中的所有语句都以原始程序顺序执行一样。
- 保留初始化排序规则(第10.5.4节和第10.5.5节)。
- 关于易失性读写(第10.5.3节),保留了副作用的顺序。 此外,执行环境不需要评估表达式的一部分,如果它可以推断出该表达式的值未被使用并且不产生所需的副作用(包括由调用方法或访问volatile字段引起的任何副作用)。 当程序执行被异步事件(例如另一个线程抛出的exception)中断时,不能保证可观察的副作用在原始程序顺序中可见。
所以我认为这意味着如果编译器或抖动可以certificate您的两个函数调用可以重新排序,甚至可以跳过,那么编译器可以自由地执行此操作。 在实践中,我认为编译器或抖动不会像代码那样执行优化,并且函数调用将同步执行。 最重要的是,出于优化原因,CPU完全可以自由地重新排序执行,并且会这样做。 当然,它不会以改变可观察输出的方式重新排序执行。
在任何情况下都有点没有意义,因为只要语言规范或CPU架构允许重新排序,只有在它对程序的含义没有任何影响时才允许。 所以,你不能通过一个心理模型来说明任何伤害,这个模型说明语句是按照同步和顺序执行的。 如果编译器和/或CPU选择重新排序,它将以不会影响程序结果的方式执行。
- LINQ – 复杂排序
- 尝试使用JSON.Net来使用SmartyStreets JSON ……“无法将JSON数组反序列化为类型组件”
- C#Winform – 如何在触摸屏上用手指移动到控制结束时防止移动整个窗口
- 如何在C#中退出Windows窗体应用程序
- System.Collections.Generic.List 的等于方法……?
- geckodriver.exe不在当前目录或路径变量中,Selenium 2.53.1 + Firefox 48 + Selenium 3 Beta
- 应用程序池模式问题:经典或集成
- MiniProfiler没有出现在asp.net MVC上
- 什么时候使用get; 组; 在c#中