简单方法在完成后再次调用

本文关键字:调用 方法 简单 | 更新日期: 2023-09-27 18:08:38

背景:

我有一个方法可以进行一些处理,我希望被一次又一次地调用。该方法可能需要50-200毫秒才能完成。

目前,我有一个System.Timers.Timer,它每250毫秒调用一次该方法。我觉得我可以通过在方法完成后让它自己"触发"来提高效率。

注:

  • 性能是关键
  • 其中两个方法不应同时调用或重叠

我希望避免简单地使用调用该方法的while循环。它应该异步调用自己——也许是使用事件?

问题:

一旦方法"触发器"完成,我怎么能让它自己?

简单方法在完成后再次调用

您可以在单独的执行线程中执行while循环,只要您对锁、条件变量、等待句柄等采取必要的多线程预防措施。

  • C#的任务并行库可能适合这份工作。但正如Reed所说,一定要使用LongRunning创建选项。Reed在这里发布了一个这个方法的例子
  • 或者直接使用Thread对象。SLaks在这里发布了一个这个方法的例子

如果您正在使用WinForms应用程序,您可能需要考虑使用BackgroundWorker。

创建一个新线程,该线程在while循环中连续调用您的方法。

void DoBackgroundPolling() {
    while(true) {
        try {
            YourMethod();
        } catch(Exception ex) {
            log error
        }
    }
}
new Thread(DoBackgroundPolling).Start()

如果您希望能够控制轮询,您可以检查该方法中的布尔字段。

public delegate void MyDelegate(void);
void MyMethod()
{
  do stuff;
  this.Dispatcher.BeginInvoke(new MyDelegate(MyMethod), null);
}

使用TPL可以相当干净地处理这一问题。在您的主线程中,您可以通过以下方式在后台启动此任务:

CancellationTokenSource cancel = new CancellationTokenSource();
Task.Factory
      .StartNew(() => PollHardware(cancel.Token), TaskCreationOptions.LongRunning)
      .ContinueWith(t =>
        {
            if (t.IsFaulted)
            {
                var aggException = t.Exception; // Keep task from pulling down AppDomain
                // Log/handle/etc
                LogException(aggException.InnerException);
            }
        });

然后,你所需要的就是一种处理循环的方法:

void PollHardware(CancellationToken token)
{
     while(true)
     {           
         token.ThrowIfCancellationRequested();
         YourMethod();
     }
} 

当您希望停止轮询时,只需调用:cancel.Cancel()即可。