了解 WPF 中提供的 DispatcherPriority 枚举的真实行为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33701510/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:32:10  来源:igfitidea点击:

Understanding the true behavior of the DispatcherPriority enum provided in WPF

c#wpfmultithreadingdispatcher

提问by William

There is documentation with definitions on what each enum does. But how am I able to demo/see this in practice? And how can I possibly know when to use which priority?

有文档定义了每个枚举的作用。但是我如何能够在实践中演示/看到这一点?我怎么可能知道什么时候使用哪个优先级?

Here's some code I have created in attempt to see how the priorty affects the ordering, and it provides me with proof that the ordering is correct (the first loop iteration will have added a SystemIdle enum to the dispatch queue), but it still got added to the string last

这是我创建的一些代码,试图查看优先级如何影响排序,它为我提供了排序正确的证据(第一次循环迭代将 SystemIdle 枚举添加到调度队列),但它仍然被添加最后到字符串

private void btn_Click(object sender, RoutedEventArgs e)
    {
        StringBuilder result = new StringBuilder();
        new Thread(() =>
            {

                var vals = Enum.GetValues(typeof(DispatcherPriority)).Cast<DispatcherPriority>().Where(y => y >= 0).ToList();
                vals.Reverse();
                vals.ForEach(x =>
                    { 
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            result.AppendLine(string.Format("Priority: {0} Enum:{1}", ((int)x), x.ToString()));
                        }), x);
                    });


            }).Start();

        ShowResultAsync(result, 2000);
    }

    private async void ShowResultAsync(StringBuilder s, int delay)
    {
        await Task.Delay(delay);
        MessageBox.Show(s.ToString());
    }

enter image description here

在此处输入图片说明

and the output order stays the same, even when the list is reversed (added this line just after valsgets assigned):

并且输出顺序保持不变,即使列表颠倒了(在vals分配之后添加了这一行):

vals.Reverse();

So once again, is there anything more I can use when determining which dispatch priority I should assign?

那么再一次,在确定我应该分配哪个调度优先级时,还有什么我可以使用的吗?

采纳答案by Ethan Cabiac

In the Prism Frameworkthe DefaultDispatcherwhich wraps Dispatcheruses a Normalpriority. This should be the bread-and-butter for nearly all application scenarios.

Prism 框架中DefaultDispatcherwhich wrapsDispatcher使用Normal优先级。这应该是几乎所有应用场景的基本要素。

/// <summary>
/// Wraps the Application Dispatcher.
/// </summary>
public class DefaultDispatcher : IDispatcherFacade
{
    /// <summary>
    /// Forwards the BeginInvoke to the current application's <see cref="Dispatcher"/>.
    /// </summary>
    /// <param name="method">Method to be invoked.</param>
    /// <param name="arg">Arguments to pass to the invoked method.</param>
    public void BeginInvoke(Delegate method, object arg)
    {
        if (Application.Current != null)
        {
            Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, method, arg);
        }
    }
}

As long as you are not running any actual logic on the UI thread I would recommend doing this.

只要您不在 UI 线程上运行任何实际逻辑,我就会建议您这样做。

If you did for some reason want to run "quick" logic on the UI thread you could follow the advice hereand stick with a value of Background.

如果您出于某种原因想要在 UI 线程上运行“快速”逻辑,您可以遵循此处的建议并坚持使用Background.

I did look into it a little and I found some usages in NuGet's sourcewhere they use Send, Normal, Backgroundand ApplicationIdlefor various reasons but in my WPF development I have never had to fine tune usage of DispatcherPriorityto this degree.

我没有看进去一点,我发现在一些使用的NuGet的来源,他们使用SendNormalBackgroundApplicationIdle由于各种原因,但在我的WPF发展我从未有过的微调使用DispatcherPriority到这种程度。