C# 返工EventWaitHandle以异步等待信号
我需要更改当前代码,以便在调用EventWaitHandle.WaitOne时不阻止当前线程。问题是我正在等待系统范围的事件。我还没有找到合适的替代品 代码:C# 返工EventWaitHandle以异步等待信号,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,我需要更改当前代码,以便在调用EventWaitHandle.WaitOne时不阻止当前线程。问题是我正在等待系统范围的事件。我还没有找到合适的替代品 代码: 我需要应用程序继续,而不是停止在我呼叫WaitOne的线路上,理想情况下会有等待。如何实现此功能?您可以在我的: 该实现使用线程池。RegisterWaitForSingleObject: public static Task<bool> FromWaitHandle(WaitHandle handle, TimeSpan t
我需要应用程序继续,而不是停止在我呼叫WaitOne的线路上,理想情况下会有等待。如何实现此功能?您可以在我的: 该实现使用
线程池。RegisterWaitForSingleObject
:
public static Task<bool> FromWaitHandle(WaitHandle handle, TimeSpan timeout)
{
// Handle synchronous cases.
var alreadySignalled = handle.WaitOne(0);
if (alreadySignalled)
return Task.FromResult(true);
if (timeout == TimeSpan.Zero)
return Task.FromResult(false);
// Register all asynchronous cases.
var tcs = new TaskCompletionSource<bool>();
var threadPoolRegistration = ThreadPool.RegisterWaitForSingleObject(handle,
(state, timedOut) => ((TaskCompletionSource<bool>)state).TrySetResult(!timedOut),
tcs, timeout);
tcs.Task.ContinueWith(_ =>
{
threadPoolRegistration.Dispose();
}, TaskScheduler.Default);
return tcs.Task;
}
来自WaitHandle的公共静态任务(WaitHandle句柄,TimeSpan超时)
{
//处理同步案件。
var alreadySignalled=handle.WaitOne(0);
如果(已签名)
返回Task.FromResult(true);
如果(超时==TimeSpan.Zero)
返回Task.FromResult(false);
//注册所有异步案例。
var tcs=new TaskCompletionSource();
var threadPoolRegistration=ThreadPool.RegisterWaitForSingleObject(句柄,
(state,timedOut)=>((TaskCompletionSource)state).TrySetResult(!timedOut),
tcs,超时);
tcs.Task.ContinueWith(=>
{
threadPoolRegistration.Dispose();
},TaskScheduler.Default);
返回tcs.Task;
}
那么,如果您不想等待,为什么要首先打电话给WaitOne?我不明白你想发生什么。我删除了我的答案,因为你需要一个系统范围的实现,而我忽略了这一点。你在寻找什么行为?您是否希望您的应用程序继续执行,并在另一个应用程序完全加载(或45秒过后)时收到通知?请签出,其中有一个工作示例。您传递的
waitObject
可以是系统范围的对象(例如,全局EventWaitHandle
),这是我需要重写的原始代码。当我们在app1的末尾使用它时,它是很好的,但是我们将代码移到了更早的时候启动,因为第二个应用程序的加载时间太长了。那么等待句柄的阻塞就是一个问题了。谢谢,在您编写第二个代码块时,我使用了很多代码。在项目中不鼓励使用额外的非.NET framework LIB如果我调用此方法10次(没有超时),那么我是否会在等待信号设置时使用10个线程池线程,这些线程现在正在阻塞?@LaFleur:No,RegisterWaitForSingleObject
能够合并调用;单线程池线程最多可以等待31个句柄。如果使用相同的句柄,则不确定行为是什么。
isOtherAppFullyLoaded = await AsyncFactory.FromWaitHandle(handle,
TimeSpan.FromMilliseconds(45000));
public static Task<bool> FromWaitHandle(WaitHandle handle, TimeSpan timeout)
{
// Handle synchronous cases.
var alreadySignalled = handle.WaitOne(0);
if (alreadySignalled)
return Task.FromResult(true);
if (timeout == TimeSpan.Zero)
return Task.FromResult(false);
// Register all asynchronous cases.
var tcs = new TaskCompletionSource<bool>();
var threadPoolRegistration = ThreadPool.RegisterWaitForSingleObject(handle,
(state, timedOut) => ((TaskCompletionSource<bool>)state).TrySetResult(!timedOut),
tcs, timeout);
tcs.Task.ContinueWith(_ =>
{
threadPoolRegistration.Dispose();
}, TaskScheduler.Default);
return tcs.Task;
}