【问题标题】:Asynchronous flow of C# programC#程序的异步流程
【发布时间】:2016-09-06 03:22:52
【问题描述】:

为了演示 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() 完成?

谢谢

【问题讨论】:

  • 阅读async关键字。你需要告诉程序异步做事情是可以的,否则它会假设它们需要按顺序完成
  • Python 也可以是异步的...
  • 旁注:考虑不要自己定义“脚本”或“编程”——这可能会导致围绕您的帖子进行不必要的讨论。这真的与你的问题无关。
  • @AlexeiLevenkov:好点:)。我将删除那部分。

标签: c# python


【解决方案1】:

C# 不会使您的程序同步。所有程序都是同步的(多核除外)。甚至操作系统也是同步运行的,并且只是通过给各种程序执行时间片来给出并行处理的错觉。如果你想让你的程序并行运行,你必须明确地告诉它。 C#/.NET 有许多机制可以做到这一点,但说一种语言是异步的是不公平的。多线程代码可以用 C 语言编写以在 Windows 上运行,但如果您在不支持并行处理的嵌入式系统上工作,则不能。

【讨论】:

    【解决方案2】:

    如果你想让 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
    

    【讨论】:

    • 您好幽灵,感谢您的回复。 C# 本身不是异步的(即不使用 async 关键字)吗?我们使用 callback() 来确保某个函数在另一个函数之后执行的原因之一。
    • 您可以使用其他构造,但 async 是最新的。如果您不使用其中一种结构,它将按顺序单独执行每条指令。
    【解决方案3】:

    这是因为每次调用方法时,在 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      相关资源
      最近更新 更多