Dispatcher方法WPF的问题 [英] Problem with Dispatcher method WPF

查看:72
本文介绍了Dispatcher方法WPF的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个控制音乐会灯光的应用程序,到目前为止,该程序进展顺利。该应用程序的主窗口代表一个物理灯板,类似于您在音乐会的声音展位中看到的。我正在为项目使用WPF。 Wpf给了我很多问题,虽然我的程序在美学方面非常华丽,但由于WPF的做法,它缺乏平滑性。



好​​的点,我有用户控制代表推子和旋钮,我想更新这些旋钮和推子以反映正在发生的事情,所以反过来,同步一切。是否有使用调度程序发送命令来更新GUI的替代方法?我使用调度员错了吗?当我需要对控件进行更改时,这就是我的代码看起来像是一个usercontrol继承的控件。



Hi, I''m currently writing an application that controls concert lights, so far the program is going very well. The main window of the application represents a physical light board, similar to what you might see in the sound booth at concerts. I''m using WPF for the project. Wpf has given me many issues, although my program is gorgeous in aesthetics, it lacks in smoothness due to WPF''s way of doing things.

Ok so to the point, I have usercontrols representing faders and knobs, I want to update these knobs and faders to reflect what is happening, so in turn, sync everything up. Is there an alternative to using the dispatcher to send commands to update the GUI? Am I using the dispatcher wrong? This is what my code looks like withing a control that is an inheritance of usercontrol when a change to the control needs to be made.

Private Sub Change(sender As Object, ByVal e As DMXProcessor.ChangeArgs)
        If channels.Count = 1 Then
            For Each z As Integer In channels
                If z = e.channel Then Slider1.Dispatcher.BeginInvoke(New MDelegate(AddressOf ChangeDispacter), e.channel, e.value)
            Next
        End If
    End Sub





什么能解决所有问题,如果我可以直接实现我的更改控件的绘制,因此每次控件由图形绘制时,控件都会检查是否需要更改,如果是,则相应地更新自身,所有这些都在同一个线程上,没有调度程序无意义。



注意:我注意到太多的调度员呼叫太近了我的程序挂起我的程序,这就是为什么我想要一个不同的方法,就像我说的,有人告诉我如果我没有正确派遣我也不介意在C#中回复,我经常使用C#来使用VB。



What would solve everything is if I could directly implement my changes within the draw of the control, so every time the control is drawn by the graphics, the control checks to see if it needs to be changed, and if so, updates itself accordingly, all on the same thread, no dispatcher nonsense.

NOTE: I''ve noticed too many dispatcher calls called too close to each other hangs my program, this is why I want a different approach, like I said, someone tell me if I''m not dispatching right. ALSO I don''t mind replies in C#, I use C# as often as I use VB.

推荐答案



它听起来可能是ChangeDispacter为UI线程做了太多工作。


It sounds likely that the ChangeDispacter is doing too much work for the UI thread.



如果是这样的话,那么一种方法是将ChangeDispacter任务分解为更小的UI操作,如下面的代码所示。这应该工作,因为看起来MDelegate没有返回值或者它不重要。这就是代码当前尝试使用的方法。


If so, then one approach is to break the ChangeDispacter task down into smaller UI operations as shown in the code below. This should work as it appears that the MDelegate has no return value or it is not significant. And that is the approach the code is currently attempting to use.

但是,如果您使用的是.NET 4.5,那么更好的解决方案是转换ChangeDispacter方法进入异步版本并同时调用它。这显示在第二个代码块中。

However, if you are using .NET 4.5, then a far better solution, is to transform the ChangeDispacter method into an Async version and call it concurrently. That is shown in the second code block.



使用当前方法:


Using the current approach:

private void Change(object sender, ChangeArgs e)
{
    if (channels.Count == 1)
    {
        foreach (int z in channels)
        {
            if (z == e.channel)
            {
                ChangeDispacterThreaded(e.channel, e.value);
            }
        }
    }
}

public void ChangeDispacterThreaded(int channel, object value)
{
    Slider1.Dispatcher.BeginInvoke(new MDelegate(ChangeDispacterUI_1)
        , new object[] { channel, value });

    // do some threaded non UI things

    Slider1.Dispatcher.BeginInvoke(new MDelegate(ChangeDispacterUI_2)
        , new object[] { channel, value });
}

public void ChangeDispacterUI_1(int channel, object value)
{
    // do UI things
}

public void ChangeDispacterUI_2(int channel, object value)
{
    // do UI things
}

.NET 4.5使用异步并发方法

.NET 4.5 Using the asynch-concurrent approach

private async Task Change(object sender, ChangeArgs e)
{
    if (channels.Count == 1)
    {
        foreach (int z in channels)
        {
            if (z == e.channel)
            {
                await ChangeDispacterThreaded(e.channel, e.value);
            }
        }
    }
}

public async Task ChangeDispacterThreaded(int channel, object value)
{
    await Slider1.Dispatcher.BeginInvoke(
        new Action<int,object>((a,b) => ChangeDispacterUI_1(a,b))
        , new object[] { channel, value });

    // do some threaded non UI things

    await  Slider1.Dispatcher.BeginInvoke(
        new Action<int, object>((a, b) => ChangeDispacterUI_1(a, b))
        , new object[] { channel, value });
}

public void ChangeDispacterUI_1(int channel, object value)
{
    // do UI things
}

public void ChangeDispacterUI_2(int channel, object value)
{
    // do UI things
}


这篇关于Dispatcher方法WPF的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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