显示 WPF-“NotifyIcon"在一个单独的线程上 [英] Displaying WPF-"NotifyIcon" on a separate thread

查看:28
本文介绍了显示 WPF-“NotifyIcon"在一个单独的线程上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个 office 插件,我需要显示一个显示进度的通知对话框,我正在使用 Philipp Sumi 的 wpf-notifyicon.

I am currently working on an office add-in and I need to show a notification dialog that displays progress, I'm using Philipp Sumi's wpf-notifyicon.

我需要从单独的线程中显示 notifyicon 因为我有一个很多已经在主线程上执行的代码,这会导致 wpf-notifyicon 阻塞并等待,因为 Windows 消息队列中的消息没有被处理.

I need to display the notifyicon from a separate thread as I have a lot of code that already executes on the main thread, this causes the wpf-notifyicon to block and wait because the messages in the windows message queue are not being processed.

我知道我应该在单独的线程上执行这段耗时的代码,并从主线程显示通知图标并相应地更新它,但不幸的是,这不是替代方案,因为整个解决方案是单线程的.

I know that I should rather execute this time consuming code on a separate thread, and display the notifyicon from the main thread and update it accordingly, but that is unfortunately not an alternative because this whole solution is single-threaded.

示例:

    private FancyPopup fancyPopup;

    private void button1_Click(object sender, EventArgs e)
    {
        notifyIcon = new TaskbarIcon();
        notifyIcon.Icon = Resources.Led;

        fancyPopup = new FancyPopup();

        Thread showThread = new Thread(delegate()
        {
            notifyIcon.ShowCustomBalloon(fancyPopup, System.Windows.Controls.Primitives.PopupAnimation.Fade, null);
        });

        showThread.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        fancyPopup.TextB.Text = "Doing something...";

        //Keep the main thread busy.
        Thread.Sleep(5000);

        fancyPopup.TextB.Text = "Done doing something...";
    }

更新使用此更新后的代码,我已经能够取得更进一步的进展:

Update I have been able to progress a little further with this updated code:

我正在一个新线程上创建 TaskbarIcon 对象,并使用 Application.Run 来处理该线程上的应用程序消息循环...

I'm creating the TaskbarIcon object on a new thread , and using Application.Run to process the application message loop on that thread...

    private FancyPopup fancyPopup;

    private void button1_Click(object sender, EventArgs e)
    {
        Thread showThread = new Thread(delegate()
        {
            notifyIcon = new TaskbarIcon();
            notifyIcon.Icon = Resources.Led;

            fancyPopup = new FancyPopup();


            notifyIcon.ShowCustomBalloon(fancyPopup, System.Windows.Controls.Primitives.PopupAnimation.Fade, null);

            System.Windows.Forms.Application.Run();
        });

        showThread.SetApartmentState(ApartmentState.STA);
        showThread.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        fancyPopup.Dispatcher.Invoke(new Action(delegate
        {
            fancyPopup.TextB.Text = "Doing something...";
        }));

        //Keep the main thread busy.
        Thread.Sleep(5000);

        fancyPopup.Dispatcher.Invoke(new Action(delegate
        {
            fancyPopup.TextB.Text = "Done doing something..."; 
        }));
    }

推荐答案

我已经解决了我的问题,我不得不在单独的 STA 线程上初始化 notifyIcon 并使用 Application.Run 以便开始在该线程上发送 Windows 消息.

I have solved my problem, I had to initialize the notifyIcon on a separate STA thread and use Application.Run in order to start pumping windows messages on that thread.

        var myThread = new Thread(delegate()
        {
            notifyIcon = new NotifyIcon();

            Application.Run();
        });

        myThread.SetApartmentState(ApartmentState.STA);
        myThread.Start();

然后我只需要调用通知对话框的 UI.

Then I just had to Invoke the UI of my notification dialog.

这篇关于显示 WPF-“NotifyIcon"在一个单独的线程上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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