-3

For example:

void Function1()
{
  Function2();
  Function3();
}

Will Function3 be guaranteed to wait until Function2 is done processing each and every time Function1 is called?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
usefulBee
  • 9,250
  • 10
  • 51
  • 89

4 Answers4

5

YES. Function3() waits untill unless Function2() execution is Completed.

if you want to invoke them independently you can use Multi-Threading concept.

EDIT: as suggested in Comments using Task is much better than Thread as it is a higher level concept.

Task Vs Thread

Try This to invoke them Independently:

using System.Threading.Tasks;

static void Main(String[] args)
        { 
            Task t1 = new Task(Function2);
            Task t2 = new Task(Function3);
            t1.Start();
            t2.Start();
        }

here we can not guarantee how the execution flow goes on.because they runindependently.

Community
  • 1
  • 1
Sudhakar Tillapudi
  • 25,935
  • 5
  • 37
  • 67
2

It's not completely clear to me what do you mean by “is done processing”.

But Function3() will be called only after Function2() returns, that's the whole idea behind imperative programming and basic C# is an imperative language.

svick
  • 236,525
  • 50
  • 385
  • 514
  • By processing I mean that any logic in Function2() will be completed before invoking Function3() – usefulBee Dec 04 '13 at 17:58
  • @workingBee If by “any logic” you mean for example things like lambdas that you wrote in that method, then that's not necessarily true. And then there are also the weird cases of `async` methods (and iterator blocks). So it's not that simple in general. – svick Dec 04 '13 at 18:01
2

Strictly speaking no. Modern CPUs, in order to improve performance, do tons and tons of optimizations under the hood. They execute things in parallel, leverage branch prediction, pipelining, etc. such that they can actually start, or even complete, operations that are supposed to happen after something that isn't actually done yet.

However, you don't need to worry about that. Great pains are taken to hide these implementation details from you. While those operations may not actually take place in the given order, it is impossible for you to ever observe the fact that they are out of order. In other words, you can always be sure that the resulting state of the computer after executing that code will be whatever it would be if the statements were executed in order. If the processor chooses to execute them out of order it will never result in a program that functions differently.

Of course, as said in the comments, this only applies to the execution of a single thread. When you have multiple threads executing there are very few guarantees about the observed order of execution of each operation.

Servy
  • 202,030
  • 26
  • 332
  • 449
1

The C# language specification says this:

3.10 Execution Order

Execution of a C# program proceeds such that the side effects of each executing thread are preserved at critical execution points. A side effect is defined as a read or write of a volatile field, a write to a non-volatile variable, a write to an external resource, and the throwing of an exception. The critical execution points at which the order of these side effects must be preserved are references to volatile fields (§10.5.3), lock statements (§8.12), and thread creation and termination. The execution environment is free to change the order of execution of a C# program, subject to the following constraints:

  • Data dependence is preserved within a thread of execution. That is, the value of each variable is computed as if all statements in the thread were executed in original program order.
  • Initialization ordering rules are preserved (§10.5.4 and §10.5.5).
  • The ordering of side effects is preserved with respect to volatile reads and writes (§10.5.3). Additionally, the execution environment need not evaluate part of an expression if it can deduce that that expression’s value is not used and that no needed side effects are produced (including any caused by calling a method or accessing a volatile field). When program execution is interrupted by an asynchronous event (such as an exception thrown by another thread), it is not guaranteed that the observable side effects are visible in the original program order.

So I take this to mean that if the compiler or jitter can prove that your two function calls can be re-ordered, or even skipped, then the compiler is free to do so. In practice I believe that the compiler or jitter will not perform an optimisation like that on your code, and that your function calls will execute synchronously. On top of that the CPU is perfectly free to re-order execution for optimisation reasons, and will do so. Of course, it won't re-order execution in a way that changes the observable output.

In any case it is somewhat moot because whenever a language specification or CPU architecture allows re-ordering, it is only allowed if it makes no difference to the meaning of your program. So, you cannot come to any harm by having a mental model that says that statements are executed synchronously and in order. If the compiler and/or CPU chooses to re-order it will do so in a way that won't affect the outcome of your program.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    `"In practice I do not believe that the compiler or JITer will do that"` It almost surely will. Modern CPUs are virtually never executing just one operation at a time. They're executing quite a few at any given instant, and they will also most certainly reorder operations quite frequently to improve performance, when they can guarantee that the result is the same. – Servy Dec 04 '13 at 18:09
  • @Servy You are talking about the CPU. I'm talking about the language. Obviously they are related., but I think that you and I are looking at this from a slightly different perspective. – David Heffernan Dec 04 '13 at 18:11
  • By the time you get to that low of a level that layer of abstraction has long since gone away. They're all just machine instructions. It's certainly possible, in fact even probable, for some of the instructions that will be used to represent the second function call will be executed before all of the instructions representing the first function call have finished. There will be a certain degree over overlap between the two functions, depending on the size of the CPU's pipeline. – Servy Dec 04 '13 at 18:13
  • If the language guaranteed that the operations were always executed in order and then called CPU instructions that reordered them then it couldn't very well guarantee an order, now could it. Of course, as you yourself just quoted, even the language doesn't guarantee order; it, like the CPUs it's abstracting, only guarantees the result is observably ordered, not actually ordered. – Servy Dec 04 '13 at 18:15
  • @Servy It comes down to where your mental model is sitting. As you said in your answer (+1 by the way), it doesn't matter that the CPU re-orders since you cannot observe that it did. – David Heffernan Dec 04 '13 at 18:16
  • I would consider the answer the same whether it's with respect to instructions in C#, instructions in MSIL, or even machine code instructions. In each of those cases the results will be observed to be in the described order, and in none of those cases is it guaranteed to actually execute in that order. Most of the re-ordering and parallelization is happening at the lowest possible level, and that re-ordering is abstracted away at one of the lowest layers of abstraction. – Servy Dec 04 '13 at 18:19
  • @Servy No, that's all wrong. Look at the quote from the spec in my answer. All written in terms of the .net execution environment. Concepts such as threads, volatile fields, lock statements and such that do not exist on CPUs. Now, clearly the C# language spec has to be written in such a way that it can be implemented on real CPUs, but I take a more layered view than you. – David Heffernan Dec 04 '13 at 18:23
  • What are you talking about? Did you read your own quote? It is worded to comply with my answer. Consider this snippet, "the value of each variable is computed as if all statements in the thread were executed in original program order." It says "as if they were executed in that order" rather than, "they will be executed in order". It only guarantees that the observable results will be the same as if it were ordered. It doesn't guarantee an order. It can't, and doesn't. That is exactly the same guarantees made of MSIL, and of machine code. At each abstraction it's the same. – Servy Dec 04 '13 at 18:26
  • @Servy I don't agree. At all. It seems to me that you are denying the possibility that the C# compiler or jitter might perform re-ordering. It does so to its rules and not the rules of the CPU. Certainly for the compiler it has to since it has no idea which CPU it will run on. – David Heffernan Dec 04 '13 at 18:29