C#程序的异步流程

时间:2016-05-10 23:27:41

标签: c# python

为了演示C#的异步流程,我编写了一个简单的程序 (显示它与Python的区别,因为Python因GIL而同步)。

为什么执行func2()等待func1()完成?

void main()
{
    Console.WriteLine("main");
    func1();
    func2();
}
public void func1()
{
    Console.WriteLine("func1");
    double i = 0;
    while(true)
    {
      i += 1;
      if (i > 100000000)
      {
       break;
      }
    }
    func(3);
    func(4);
}
public void func2()
{
    Console.WriteLine("func2");
    func(5);
    func(6);
}
public void func(int number)
{
    Console.WriteLine(number);
}

在func1()中,我正在运行一个循环来使程序等待,以便main()继续运行并在func(3)和func(4)之前调用func2()。但每次都以同步方式运行并按此顺序打印输出:

main
func1
3
4
func2
5
6

即。 func2()总是在func4()之后调用,我在异步流程中没有想到。

为什么执行func2()等待func1()完成?

谢谢

3 个答案:

答案 0 :(得分:4)

C#不会使您的程序同步。所有程序都是同步的(多核除外)。即使操作系统同步运行,也只是通过为各种程序提供执行时间片来给出并行处理的错觉。如果您希望程序并行运行,则必须明确说明。 C#/ .NET有很多机制可以做到这一点,但说一种语言是异步的并不公平。多线程代码可以用C语言编写,以便在Windows上运行,但是如果您正在使用不支持并行处理的嵌入式系统,则无法进行。

答案 1 :(得分:1)

如果你想让func2不等待func1完成,你需要告诉它:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("main");
        doWork();
    }
    public async static void doWork()
    {
        Task<int> longTask = func1(); //Start func1
        func2(); //Call func2 while we wait
        int output = await longTask; //Wait for func2 to be finished
    }
    public async static Task<int> func1()
    {
        Console.WriteLine("func1");

        await Task.Delay(10000); //delay, could make func(3) and func(4) run in the meantime if we wanted....

        func(3);
        func(4);
        return 0;
    }
    public static void func2()
    {
        Console.WriteLine("func2");
        func(5);
        func(6);
    }
    public static void func(int number)
    {
         Console.WriteLine(number);
    }
}

输出:

main
func1
func2
5
6
3
4

答案 2 :(得分:1)

这是因为每次调用方法时,在C#中,传递给参数的信息都存储在堆栈(调用堆栈)中。该堆栈首先实现为第一个。 所以在你的例子中,当func1被调用它进入堆栈时,main方法将停止并等待func1离开堆栈。 https://en.wikipedia.org/wiki/Call_stack

如果没有异步流,没有办法做你想做的事情,我怀疑python也是如此。

但是,您可以轻松地更改代码以异步执行它。

    public static void Main()
{
    Console.WriteLine("main");
    var t = func1();
    func2();
    t.Wait();
}

public static Task func1()
{
    Console.WriteLine("func1");
    return Task.Factory.StartNew(() => {
        double i = 0;
        while(true)
        {
          i += 1;
          if (i > 100000000)
          {
           break;
          }
        }
        func(3);
        func(4);
    });
}
public static void func2()
{
    Console.WriteLine("func2");
    func(5);
    func(6);
}
public static void func(int number)
{
    Console.WriteLine(number);
}