简体   繁体   English

从另一个线程异步更新wpf UI

[英]Updating wpf UI from another thread asynchronously

I have a WPF UI and I want to update it asynchronously from another thread by calling some events. 我有一个WPF UI,我想通过调用一些事件从另一个线程异步更新它。

I know how to call events and invoke them in UI Thread, but I want to do it async. 我知道如何调用事件并在UI线程中调用它们,但我想使其异步。

public partial class HomeUI 
{
    public HomeUI()
    {
        var test = new LogicClass();
        test.UI_StartPlaying += StartPlaying;

        new Thread(test.Start).Start();
    }

    private void StartPlaying(object sender, EventArgs e)
    {
        Dispatcher.Invoke(new Action(() =>
        {
            var streamAddress = (e as UIUpdateEventArgs).StreamAddress;
            vlc.Stop();
            vlc.Media = new LocationMedia(streamAddress);
            vlc.Play();
        }));
    }

}


public class LogicClass
{
    public event EventHandler UI_StartPlaying;
    public void Start()
    {
        DoSomethings();
        UI_StartPlaying(this, new UIUpdateEventArgs(streamAddress));
        DoSomethingElse();
    }
}

class UIUpdateEventArgs : EventArgs
{
    string StreamAddress {get; set;}
    public UIUpdateEventArgs( string streamAddress)
    {
        this.StreamNumber = streamNumber;
    }
}

but in this code, when something happening in DoSomethingElse() part that cause delay or stop the logic thread, UI freezes. 但是在这段代码中,当DoSomethingElse()部分中发生某些导致延迟或停止逻辑线程的事件时,UI会冻结。
Edit: in DoSomethingElse() part, I run 2 Threads that one of them do all the DB transactions and have some delay. 编辑:DoSomethingElse()部分中,我运行2个线程,其中之一执行所有数据库事务,并且有一些延迟。 this delay, make the vlc pause (freeze on a random frame) on the UI and then make the whole UI freeze. 此延迟,使vlc在UI上暂停(冻结在随机帧上),然后冻结整个UI。
Obviously, when I comment these transactions, program work properly. 显然,当我评论这些事务时,程序可以正常工作。
What should I do to make the UIEventUpdate run asynchronously with my Logic Thread ? 如何使UIEventUpdateLogic Thread异步运行?

You can use Dispatcher.BeginInvoke to get what you need. 您可以使用Dispatcher.BeginInvoke获得所需的内容。 This function is returning directly, the delegate gets scheduled and called later. 该函数直接返回,委托得到调度并稍后调用。

If your requirement is that DoSomethingElse() is called after StartPlaying finished, you have to await the Dispatcher.BeginInvoke call. 如果您要求在StartPlaying完成之后调用DoSomethingElse() ,则必须await Dispatcher.BeginInvoke调用。

I don´t know about LocationMedia but if new LocationMedia(streamAddress); 我不知道LocationMedia但是是否有new LocationMedia(streamAddress); is an expensive creation (takes long and/or needs lot of memory) i would do it outside the Dispatcher delegate if possible. 是一个昂贵的创建(需要很长时间和/或需要大量内存),如果可能的话,我会在Dispatcher委托之外进行。

var streamAddress = (e as UIUpdateEventArgs).StreamAddress;
var media = new LocationMedia(streamAddress);
Dispatcher.BeginInvoke(new Action(() =>
{
    vlc.Stop();
    vlc.Media = media;
    vlc.Play();
}));

Greetings! 问候!

Use Dispatcher.InvokeAsync Method instead of Invoke method. 使用Dispatcher.InvokeAsync方法而不是Invoke方法。 MSDN Link MSDN链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM