延迟调度调用?

Hom*_*mde 16 .net wpf dispatcher

在WPF中,由于接口更新的复杂性,我有时必须在短暂的延迟后执行操作.

目前我这样做只是通过:

        var dt = new DispatcherTimer(DispatcherPriority.Send);
        dt.Tick += (s, e) =>
        {
            dt.Stop();
            //DoStuff
        };
        dt.Interval = TimeSpan.FromMilliseconds(200);
        dt.Start();
Run Code Online (Sandbox Code Playgroud)

但是每次创建一个新的计时器都有点丑陋和开销可能太多(?)从性能的角度来看,最好的做法是什么,即最快地执行?有什么好的方法可以将上面的代码改写成:

        this.Dispatcher.BeginInvoke(new Action(delegate()
        {
            //DoStuff
        }), DispatcherPriority.Send,TimeSpan.FromMilliseconds(200));
Run Code Online (Sandbox Code Playgroud)

Timespan是延迟的地方,感谢任何输入:)

Jon*_*eet 12

我不会认为DispatcherTimer是重量级的...为什么不写一个扩展方法Dispatcher,允许你使用你想要的语法,并DispatcherTimer在后台使用?我个人称之为DelayInvoke而不是BeginInvoke...而且我也会将其修复为始终使用Action而不是任意委托...这将使得使用lambda表达式更容易:

Dispatcher.DelayInvoke(TimeSpan.FromMilliseconds(200), () => { ... 
});
Run Code Online (Sandbox Code Playgroud)

(如果匿名函数被用作方法调用中的最后一个参数,我倾向于发现它更具可读性,但这只是个人偏好.)

鉴于你很可能想要在大多数时间使用毫秒,你也可以使用另一个辅助方法:

Dispatcher.DelayInvokeMillis(200, () => { ... 
});
Run Code Online (Sandbox Code Playgroud)

try的另一种替代方法是仅使用现有BeginInvoke方法,但优先级非常低,因此只有在其他所有方法完成后才会调用您的委托.如果不了解您的具体情况,很难知道这是否有效 - 但值得尝试.

  • @MattiasK:我刚刚检查过,你可以告诉DispatcherTimer构造函数它应该在哪个Dispatcher上运行 - 所以你要使用扩展方法中的重载,并指定传递给方法的Dispatcher. (2认同)

Ant*_*ard 8

一种.NET 4.5方式:

    public async void MyMethod()
    {
        await Task.Delay(20); 
        await Dispatcher.BeginInvoke((Action)DoStuff);
    }
Run Code Online (Sandbox Code Playgroud)