13

我正在尝试从基于事件的异步模式转换,在该模式中我使用唯一 ID 和异步操作管理器跟踪运行方法。
由于这已从 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 并查看它的状态和 async 方法的 .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();
        }
    }
4

3 回答 3

8

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-异步 apis.aspx。迁移到这里应该只是调用IProgress委托而不是Progress事件的问题。

于 2012-08-23T20:27:42.373 回答
3

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

话虽如此,await在操作完成、引发异常或取消之前不会“返回”。您基本上可以放心地假设,如果您仍在等待“等待”,则您的任务尚未完成。

于 2012-08-23T18:56:33.840 回答
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 **
}

额外的好处是您可以看到队列中有多少项目!

于 2015-07-17T04:39:47.260 回答