为了演示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()完成?
谢谢
答案 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);
}