Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SemaphoreSlim.WaitAsync如何允许异步函数的顺序执行?_C#_Multithreading_Asynchronous_Semaphore - Fatal编程技术网

C# SemaphoreSlim.WaitAsync如何允许异步函数的顺序执行?

C# SemaphoreSlim.WaitAsync如何允许异步函数的顺序执行?,c#,multithreading,asynchronous,semaphore,C#,Multithreading,Asynchronous,Semaphore,这个问题的上下文是WPF应用程序。WPF应用程序使用DispatcherSynchronizationContext 如果我的应用程序中有一个按钮调用button_Click handler方法,并且我想确保该函数中的所有代码只由一个线程执行,那么我会将其包装在一个信号量中,如图所示?但我不明白这是怎么回事 假设按钮被点击,我们会点击WaitAsync(),它会返回一个任务,当输入信号量时该任务就会完成,所以我猜是立即完成的吗?然后我们将点击wait GetLengthAsync(),它将把我们

这个问题的上下文是WPF应用程序。WPF应用程序使用DispatcherSynchronizationContext

如果我的应用程序中有一个按钮调用button_Click handler方法,并且我想确保该函数中的所有代码只由一个线程执行,那么我会将其包装在一个信号量中,如图所示?但我不明白这是怎么回事

假设按钮被点击,我们会点击WaitAsync(),它会返回一个任务,当输入信号量时该任务就会完成,所以我猜是立即完成的吗?然后我们将点击wait GetLengthAsync(),它将把我们返回到wpf消息循环。假设10秒过去了,再次单击按钮,那么我们将再次输入button_Click方法并点击WaitAsync(),它返回一个任务,当我们输入信号量时该任务完成,而我们无法输入信号量,因此我们将返回到消息循环?这就是它的工作原理吗

主要问题- 我们两次点击WaitAsync()都是在同一个线程上,我们的信号量限制并发性,一次只允许一个线程执行该代码块,但它也不允许同一个线程输入该代码?信号量显然不能通过其他线程(比如thread4或thread5)获得,但它也不能通过同样的线程获得?如有任何澄清,将不胜感激

private-SemaphoreSlim-SemaphoreSlim=new-SemaphoreSlim(1,1);
公共异步无效按钮\u单击(对象发送方、事件args args)
{
等待信号量lim.WaitAsync();
尝试
{
//GetLengthAsync需要40秒才能完成
int length=等待GetLengthAsync();
//LongComputeFunc需要30秒才能完成
int aggregate=LongComputeFunc(长度);
}
最后
{
semaphoreSlim.Release();
}
}
假设按钮被点击,我们会点击WaitAsync(),它会返回一个任务,当输入信号量时该任务就会完成,所以我猜是立即完成的吗?然后我们将点击wait GetLengthAsync(),它将把我们返回到wpf消息循环

对,对

假设10秒过去了,再次单击按钮,那么我们将再次输入button_Click方法并点击WaitAsync(),它返回一个任务,当我们输入信号量时该任务完成,而我们无法输入信号量,因此我们将返回到消息循环?这就是它的工作原理吗

主要问题-两次使用WaitAsync()时,我们都在同一个线程上,信号量限制并发性,一次只允许一个线程执行该代码块,但也不允许同一个线程进入该代码块?信号量显然不能通过其他线程(比如thread4或thread5)获得,但它也不能通过同样的线程获得

这是正确的。一些同步协调原语确实能够允许递归锁(例如,
监视器
),但其他原语则不能(例如,
互斥锁
)。然而,异步协调原语支持递归锁是不自然的。(就我个人而言,我很高兴)。同步协调原语可以避开递归,因为存在“拥有”锁的“线程”概念。对于异步协调原语,没有线程拥有锁的概念;相反,“代码块”拥有锁

因此,这是一种冗长的说法,即
SemaphoreSlim.WaitAsync
不是递归的(也不应该是递归的)

现在,这是否是一个好的用户体验设计是一个不同的问题。如注释中所述,如果您一次只想启动一个按钮,则UI通常会禁用表示长时间运行的操作的按钮。也就是说,如果您希望允许用户对多个长期运行的操作排队,那么可以使用
信号量lim
方法。在本例中,
信号量lim
的作用类似于代码的一种隐式队列

假设按钮被点击,我们会点击WaitAsync(),它会返回一个任务,当输入信号量时该任务就会完成,所以我猜是立即完成的吗?然后我们将点击wait GetLengthAsync(),它将把我们返回到wpf消息循环

对,对

假设10秒过去了,再次单击按钮,那么我们将再次输入button_Click方法并点击WaitAsync(),它返回一个任务,当我们输入信号量时该任务完成,而我们无法输入信号量,因此我们将返回到消息循环?这就是它的工作原理吗

主要问题-两次使用WaitAsync()时,我们都在同一个线程上,信号量限制并发性,一次只允许一个线程执行该代码块,但也不允许同一个线程进入该代码块?信号量显然不能通过其他线程(比如thread4或thread5)获得,但它也不能通过同样的线程获得

这是正确的。一些同步协调原语确实能够允许递归锁(例如,
监视器
),但其他原语则不能(例如,
互斥锁
)。然而,异步协调原语支持递归锁是不自然的。(就我个人而言,我很高兴)。同步协调原语可以避开递归,因为存在“拥有”锁的“线程”概念。对于异步协调原语,没有线程拥有锁的概念;相反,“代码块”拥有锁

因此,这是一种冗长的说法,即
SemaphoreSlim.WaitAsync
不是递归的(也不应该是递归的)

现在,这是否是一个好的用户体验设计是一个不同的问题。如注释中所述,如果您一次只想启动一个按钮,则UI通常会禁用表示长时间运行的操作的按钮。也就是说,你