2017-05-26 24 views
0

我有一个类(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事件被调用的代码是同步的。

回答

3

请勿使用BeginInvoke/EndInvoke。这些方法仅在线程池线程上调用Invoke

使用myEvent?.Invoke()是提升事件的适当方式,它(同步)设置AsyncManualResetEventAsyncManualResetEvent上有一个异步听众这一事实并不重要。

在一个侧面说明,AsyncEx的最新(V5预览)版本包括PauseToken /PauseTokenSource类型的其实只是围绕AsyncManualResetEvent一个简单的包装,但可能使代码更清楚一点的意图。