Dispatcher.InvokeAsync-仅在a尚未运行时检查它是否被调用 [英] Dispatcher.InvokeAsync - check that a is called only if it is not already running

查看:284
本文介绍了Dispatcher.InvokeAsync-仅在a尚未运行时检查它是否被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好

我的DLL中有一个线程,该线程在exe程序中大约每20毫秒调用一次委托.

I've a thread in my DLL that invokes about every 20ms a delegate in my exe program.

此委托实现了一种必须更新WPF GUI(例如网格)的方法.

This delegate implement a method that must update a WPF GUI (for example a Grid).

private MyDelegateMethodCalledFromDllThread()
{
  ..
  ..
  Application.Current.Dispatcher.InvokeAsync(new Action(() => DoUpdates()), DispatcherPriority.ApplicationIdle);
  ..
  ..
}

DoUpdates方法被调用了几次,可能是因为同一个方法比线程慢.我想如果DoUpdates方法正在运行,直到完成后才调用另一个方法.

DoUpdates method is called several times, probably because the same method is slower than the thread. I want if the method DoUpdates is running, it is not called another until it is finished.

有可能吗?

谢谢

Stefano

推荐答案

与Invoke Async 方法不同,Invoke方法不会返回-它将阻塞-直到在UI线程上执行了传递给它的委托为止:

Unlike the InvokeAsync method, the Invoke method won't return - it will block - until the delegate that you pass to it has been executed on the UI thread:

private MyDelegateMethodCalledFromDllThread()
{
  ..
  ..
  Application.Current.Dispatcher.Invoke(new Action(() => DoUpdates()), DispatcherPriority.ApplicationIdle);
  ..
  ..
}


您还可以通过使用同步原语(例如锁)来确保一次只有一个线程可以输入MyDelegateMethodCalledFromDllThread()方法:

You could also ensure that only one thread at a time can enter the MyDelegateMethodCalledFromDllThread() method by using a synchronization primitive such as a lock:

        private readonly object _lock = new object();
        private MyDelegateMethodCalledFromDllThread()
        {
            lock(_lock) //<- threads will queue up here
            {
                //only one thread at time can enter this block (critical section)
                Application.Current.Dispatcher.Invoke(new Action(() => DoUpdates()), DispatcherPriority.ApplicationIdle);
            }
        }


>>我想要DoUpdates方法是否正在运行,直到完成后才调用另一个方法.


>>I want if the method DoUpdates is running, it is not called another until it is finished.

如果始终始终在同一线程(即UI线程)上运行此方法,则永远不会同时执行两次对DoUpdates()方法的调用. .

Two calls to the DoUpdates() method will never be executed simultaneously provided that you always run this method on the same thread, i.e. the UI thread. It might still be called several times, one after another, though.

如果您不希望这样做,则需要定义一个最大间隔来调用该方法,然后,如果自上次调用以来未经过此时间,则不要调用该方法,例如:

If you don't want this you need to define some maximum interval at which you want to invoke the method and then simply don't call the method if this amount of time hasn't elapsed since the last call, e.g.:

        DateTime lastRunTime;
        private MyDelegateMethodCalledFromDllThread()
        {
            if(lastRunTime == DateTime.MinValue || DateTime.Now.Subtract(lastRunTime).TotalMilliseconds >= 500) //only call the method once every 500 ms
                Application.Current.Dispatcher.Invoke(new Action(() => DoUpdates()), DispatcherPriority.ApplicationIdle);

            lastRunTime = DateTime.Now;
        }

希望有帮助.

请记住,通过将有用的帖子标记为答案来关闭话题,然后在遇到新问题时开始新话题.请不要在同一线程中问几个问题.

Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.


这篇关于Dispatcher.InvokeAsync-仅在a尚未运行时检查它是否被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆