我有一个类(Class A
)负责在后台运行异步作业,如下所示:
public async void DoJob()
{
while (true)
{
var thingToDo = this.getNextThing();
if (thingToDo != null)
{
try
{
await this.performAction(thingToDo);
}
catch (Exception ex)
{
// file logging of error.
// then wait a certain period.
await Task.Delay(someInterval);
}
}
else
{
// Gets the interval that should be awaited until there is a
// thingToDo available.
var waitInterval = this.getWaitUntilNextThingAvailable();
// if there such an interval then wait for it.
if (waitInterval != null)
{
await Task.Delay(waitInterval.Value);
}
// else (basically when there is nothing to be done by this job)
// use an AsyncManualResetEvent to wait until its set.
else
{
await this.waitHandle.WaitAsync();
}
}
}
}
我基本上对上一个else
块感兴趣 - 我使用AsyncManualResetEvent
的块(由AsyncEx库提供)
我使用另一个类(Class B
)提供的事件来设置waitHandle
。这是订阅的样子(注意此方法在Class B
)
private event Action ChangeOccurred;
public void Attach(Action action)
{
this.ChangeOccurred += action;
}
现在我的问题是:我使用ChangeOccurred?.Invoke()
来设置waitHandle
,以便可以通知Class A
有事可做并继续在后台执行操作。
Invoke()
是正确的方法吗?我不确定是否应该使用BeginInvoke()
和EndInvoke
代替?该事件不包含日期,仅用作异步作业可以执行的signal
。
Class B
中调用ChangeOccurred
事件的代码是同步的。
答案 0 :(得分:3)
请勿使用BeginInvoke
/ EndInvoke
。这些方法只是在线程池线程上调用Invoke
。
使用myEvent?.Invoke()
是提升事件的适当方式,它(同步)设置AsyncManualResetEvent
。 AsyncManualResetEvent
上存在异步侦听器的事实并不重要。
另一方面,AsyncEx的最新版本(v5预览版)包括PauseToken
/ PauseTokenSource
类型实际上只是AsyncManualResetEvent
的简单包装,但可能会使代码的意图更清晰。