C# SemaphoreSlim.WaitAsync如何允许异步函数的顺序执行?
这个问题的上下文是WPF应用程序。WPF应用程序使用DispatcherSynchronizationContext 如果我的应用程序中有一个按钮调用button_Click handler方法,并且我想确保该函数中的所有代码只由一个线程执行,那么我会将其包装在一个信号量中,如图所示?但我不明白这是怎么回事 假设按钮被点击,我们会点击WaitAsync(),它会返回一个任务,当输入信号量时该任务就会完成,所以我猜是立即完成的吗?然后我们将点击wait GetLengthAsync(),它将把我们返回到wpf消息循环。假设10秒过去了,再次单击按钮,那么我们将再次输入button_Click方法并点击WaitAsync(),它返回一个任务,当我们输入信号量时该任务完成,而我们无法输入信号量,因此我们将返回到消息循环?这就是它的工作原理吗 主要问题- 我们两次点击WaitAsync()都是在同一个线程上,我们的信号量限制并发性,一次只允许一个线程执行该代码块,但它也不允许同一个线程输入该代码?信号量显然不能通过其他线程(比如thread4或thread5)获得,但它也不能通过同样的线程获得?如有任何澄清,将不胜感激C# SemaphoreSlim.WaitAsync如何允许异步函数的顺序执行?,c#,multithreading,asynchronous,semaphore,C#,Multithreading,Asynchronous,Semaphore,这个问题的上下文是WPF应用程序。WPF应用程序使用DispatcherSynchronizationContext 如果我的应用程序中有一个按钮调用button_Click handler方法,并且我想确保该函数中的所有代码只由一个线程执行,那么我会将其包装在一个信号量中,如图所示?但我不明白这是怎么回事 假设按钮被点击,我们会点击WaitAsync(),它会返回一个任务,当输入信号量时该任务就会完成,所以我猜是立即完成的吗?然后我们将点击wait GetLengthAsync(),它将把我们
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通常会禁用表示长时间运行的操作的按钮。也就是说,你