C# WinRT CoreDispatcher运行异步和闭包

C# WinRT CoreDispatcher运行异步和闭包,c#,windows-runtime,dispatcher,synchronizationcontext,C#,Windows Runtime,Dispatcher,Synchronizationcontext,WinRT CoreDispatcher具有RunAsync方法,该方法实际上不接受状态变量 翻译:在大多数常见情况下,通过向调度器发送的每一个通知都会由于关闭而在内部分配。一个简单而重要的设计被忽略了,这很令人担忧 例如:一个实现INotifyPropertyChanged的简单常见示例需要一个方法,其结果如下: protected virtual void NotifyPropertyChanged( [CallerMemberName] string propertyName =

WinRT CoreDispatcher具有RunAsync方法,该方法实际上不接受状态变量

翻译:在大多数常见情况下,通过向调度器发送的每一个通知都会由于关闭而在内部分配。一个简单而重要的设计被忽略了,这很令人担忧

例如:一个实现INotifyPropertyChanged的简单常见示例需要一个方法,其结果如下:

    protected virtual void NotifyPropertyChanged(
[CallerMemberName] string propertyName = null)
    {
            var handler = PropertyChanged;

            if (handler != null)
            {
                // Check access first, and then at some point pass it along.
                Dispatcher.RunAsync(() => 
    handler(this, new PropertyChangedEventArgs(propertyName)));
            }
    }
现在,每次调用一个简单的prop-changed通知时,编译器都会在后台分配一个新类,这对于很多通知来说都很糟糕。这使得我们可以回到SynchronizationContext.Post,这是一个更有效的选项,当有很多通知时,考虑到它有一个状态变量,处理程序和propertyName可以一起传递


如果您对如何在这种情况下与调度员协作有任何建议或想法,我们将不胜感激。

我认为您不必为此担心。使用闭包可能很好;我怀疑你会发现任何明显的性能下降

请注意,在其他情况下,您可以将参数传递给被调用的方法,但最终还是得到了一个分配。至少必须分配一个
对象[]
,以包含参数。此外,值类型参数最后必须装箱:更多的分配

因此,在我看来,闭包在最坏的情况下是相同的,在某些情况下可以更有效地分配,因为在该情况下不必对值类型进行装箱

如果您确实发现自己处于分配影响性能的场景中,那么您可以显式地实现自己的闭包并重用实例。即,创建一个显式使用的类,该类包含通常捕获的任何变量,并且包含要执行的代码。然后分配其中一个(或池中的多个),并为每次调用重用实例


但真的,我怀疑你是否能找到一个令人信服的理由去惹那么多麻烦。

我明白你的意思。我想在这种情况下使用游泳池似乎是最好的主意。谢谢,我没想到会因为什么原因去游泳池。我正在看一个使用INotifyPropertyChanged处理程序的日志视图的场景。因此,每秒有数百个事件。:)FWIW,对于现代PC和.NET来说,每秒100次的事件根本算不上什么。即使1000/秒也不会对计算机征税。以这种速度,我可以保证,由于使用闭包来处理每个事件,您不会遇到任何重大的性能问题。毫无疑问,即使是数千个事件也几乎没有任何意义。但这只是记录者。记录100秒的事件意味着100秒的征税操作已经在运行。:)无论如何,通用对象状态仍然会更有效。因为一个Action、T state和一个用于多个参数的类似元组的结构相结合,应该能够在堆上实现零分配。“记录100秒的事件意味着已经运行了100秒的税务操作。”这正好强化了我的观点。在这些事件的上下文中,单个分配(以及最终的集合……分配本身实际上是免费的,而成本,无论多么无关紧要,都是在执行GC时产生的)并不重要。记住,
Action
也是一个对象,同样,在没有强类型容器的情况下传递值类型意味着装箱(更多的分配)。NET设计用于处理大量分配;在你有证据之前别担心。