【问题标题】:Does Dispatcher.BeginInvoke queues the call if it is called from the same thread?如果从同一个线程调用 Dispatcher.BeginInvoke 是否对调用进行排队?
【发布时间】:2019-01-23 16:49:19
【问题描述】:

如果我有这样的电话:

Application.Current.Dispatcher.BeginInvoke(() => someAction);

从 Dispatcher 线程调用的它是排队等待稍后执行还是立即执行,因为它不需要从一个线程更改为另一个线程?

【问题讨论】:

    标签: c# .net dispatcher begininvoke


    【解决方案1】:

    正如其他人指出的那样,它确实会排队。解决此问题的一个有用方法是定义:

    public void DispatchIfNecessary(Action action) {
        if (!Dispatcher.CheckAccess())
            Dispatcher.Invoke(action);
        else
            action.Invoke();
    }
    

    可以这样称呼:

    DispatchIfNecessary(() => {
        someAction...
    });
    

    【讨论】:

      【解决方案2】:

      它是排队等待稍后执行还是立即执行 因为它不需要从一个线程更改为另一个线程?

      仍在排队。没有检查从哪个上下文调用该方法。可以看in the source:

      private void InvokeAsyncImpl(DispatcherOperation operation,
                                   CancellationToken cancellationToken)
      {
          DispatcherHooks hooks = null;
          bool succeeded = false;
      
          // Could be a non-dispatcher thread, lock to read
          lock(_instanceLock)
          {
              if (!cancellationToken.IsCancellationRequested &&
                  !_hasShutdownFinished && 
                  !Environment.HasShutdownStarted)
              {
                  // Add the operation to the work queue
                  operation._item = _queue.Enqueue(operation.Priority, operation);
      
                  // Make sure we will wake up to process this operation.
                  succeeded = RequestProcessing();
      
                  if (succeeded)
                  {
                      // Grab the hooks to use inside the lock; but we will
                      // call them below, outside of the lock.
                      hooks = _hooks;
                  }
                  else
                  {
                      // Dequeue the item since we failed to request
                      // processing for it.  Note we will mark it aborted
                      // below.
                      _queue.RemoveItem(operation._item);
                  }
              } 
          }
      
          // Rest of method, shortened for brevity.
      }
      

      【讨论】:

        【解决方案3】:

        在 Dispatcher 线程中运行代码并且所有其他排队的 BeginInvoke 完成执行后,它会排队等待执行

        【讨论】:

          猜你喜欢
          • 2014-08-20
          • 1970-01-01
          • 2012-05-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多