如何在 C# 中延迟方法调用

本文关键字:延迟 方法 调用 | 更新日期: 2023-09-27 18:33:02

有没有办法在当前用户输入处理完成后安排方法调用?类似于将用户消息发布到消息队列。

让我们来看看如何处理用户输入:

1. User taps the screen                                      |  User input
2. Operating system puts a message in message queue          |  Operating system
3. WPF internals pick up the message                         '
4. WPF internals processes the message                        | WPF internals
5. WPF causes parts of application code to be run:           /
    a) As immediate reactions on events                      '  This is where call may
    b) As an effect of dependency properties being changed   /  be scheduled
6. The application code finishes                             |  Application code
7. The WPF internals finishes their work                     |  WPF internals
   *** This is where I want the scheduled method to run ***
8. WPF peeks for next message from message queue             |  WPF internals

如何安排通话,以便它在我想要的地方发生?

如何在 C# 中延迟方法调用

如果我正确理解您的问题,那么这就是我解决它的方式。

  1. 声明 2 个全局变量:

    Action<object> gPostProcessingMethod = null;//it must be accessible to any of the methods
                           // that may decide to schedule post-processing of your message
    object gDataForPostProcessing = null;//it will hold a data for post-processing (if any)
    
  2. 我假设您在某处有一个循环来轮询您的消息队列。让我们假设这是while循环。然后它应该看起来像这样来处理消息的后处理:

        while (...)
        {
            // 1. Your code to dequeue/get next message:
            // .................................
            gPostProcessingMethod= null;
            gDataForPostProcessing = null;
            /* 2. Your code that triggers processing of the message. As far as I understand,
                  this triggering method does not return until all of the subsequently called
                  methods are done.
                  However, as you described, any of those methods may decide to schedule 
                  "post-processing" method that must start at the moment the processing is complete.
                  This is how the scheduling should be done: 
                      gPostProcessingMethod = <AnyMethodThatCompliesWithSignatureOfAction>  
                      gDataForPostProcessing = ...;
            */
    
            if (gPostProcessingMethod != null)
            {//You mentioned that this call MUST happen synchronously (otherwise you may use ThreadPool, etc.)
                 gPostProcessingMethod(gDataForPostProcessing);
            }
            // 3. Your remaining code in the loop:
            // ......................................
        }
    
  3. 由于每个后续处理方法都可以覆盖先前分配给gPostProcessingMethodgDataForPostProcessing的值,因此您应该接受下游方法具有优先级或相反:如果已经设置了这些变量,则禁止更改这些变量。

有很多方法可以做到这一点。我个人倾向于实现这种类型的行为是使用 ConcurrentQueue<>

您可以使用信号量进行多线程处理,或者当单线程只是一个在方法开始时增加并在方法结束时递减的整数时。您只需等到这回到零。