如何跟踪异步/等待任务是否正在运行

时间:2012-08-23 18:52:59

标签: c# .net

我正在尝试从基于事件的异步模式转换,我使用唯一的id和asynoperationmanager跟踪运行方法。
由于这已经从Windows 8应用程序中删除了,我试图通过Async / Await获得类似的效果,但无法弄清楚如何。
我想要实现的是像

private async Task updateSomething()
{
    if(***the method is already running***)
    {
        runagain = true;
    }
    else
    {
        await someMethod();
        if (runagain)
        {
            run the method again
        }            
    }
}

我正在努力解决的问题是找出该方法是否正在运行。我已经尝试创建一个Task并查看as和异步方法的.status的状态,但它们看起来并不正确。 感谢

更新:这是我在.net 4中使用的当前代码,以实现相同的结果。 _updateMetaDataAsync是一个基于基于事件的异步模式的类。

private void updateMetaData()
    {
        if (_updateMetaDataAsync.IsTaskRunning(_updateMetaDataGuid_CheckAllFiles))
        {
            _updateMetaDataGuid_CheckAllFiles_Again = true;
        }
        else
        {
            _updateMetaDataGuid_CheckAllFiles_Again = false;
            _updateMetaDataAsync.UpdateMetaDataAsync(_updateMetaDataGuid_CheckAllFiles);
        }
    }

private void updateMetaDataCompleted(object sender, UpdateMetaDataCompletedEventArgs e)
    {
        if (_updateMetaDataGuid_CheckAllFiles_Again)
        {
            updateMetaData();
        }
    }

3 个答案:

答案 0 :(得分:7)

async / await本身旨在用于创建从UI线程异步执行的顺序操作。您可以让它执行并行操作,但通常操作会“加入”到具有某种结果的UI线程。 (还有可能使用await执行“即发即弃”类型的异步操作,但不建议这样做。即async / await没有任何固有支持进度报告的内容。

可以使用async / await从代码中取得进展;但您需要使用IProgress<T>之类的新进度界面。有关使用async / await进度报告的详细信息,请参阅http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx。迁移到此应该只需要调用IProgress代理而不是Progress事件。

答案 1 :(得分:2)

如果您使用的是您创建的Task,则可以查看任务的Status属性(或只看Task.IsCompleted如果完成是您感兴趣的唯一状态)

话虽这么说,await将不会“返回”,直到操作完成,引发异常或取消。你基本上可以安全地假设,如果你还在等待“等待”,你的任务还没有完成。

答案 2 :(得分:0)

SemaphoreSlim queueToAccessQueue = new SemaphoreSlim(1);
object queueLock = new object();
long queuedRequests = 0;
Task _loadingTask;
public void RetrieveItems() {
  lock (queueLock) {
      queuedRequests++;
      if (queuedRequests == 1) { // 1 is the minimum size of the queue before another instance is queued
        _loadingTask = _loadingTask?.ContinueWith(async () => {
          RunTheMethodAgain();
          await queueToAccessQueue.WaitAsync();
          queuedRequests = 0; // indicates that the queue has been cleared;
          queueToAccessQueue.Release()
        }) ?? Task.Run(async () => {
          RunTheMethodAgain();
          await queueToAccessQueue.WaitAsync();
          queuedRequests = 0; // indicates that the queue has been cleared;
          queueToAccessQueue.Release();
        });
      }
  }
}
public void RunTheMethodAgain() {
  ** run the method again **
}

额外的好处是你可以看到队列中有多少物品!