C#/ WPF - 为什么这个单独的线程在单独的表单上挂起整个应用程序?

时间:2014-06-10 16:37:24

标签: c# wpf multithreading

问题

我正在编写软件,用于检测哪些活动屏幕处于打开状态,并将ping命令发送到主应用程序以获取建议。问题是,无论我尝试过什么,每当我在一个单独的形式OR线程中激活无限循环时,它都会挂起整个应用程序,并涉及所有形式。

我尝试了什么
是的,这些类位于同一名称空间中 是的我曾经尝试过后台工作人员 是的我确实意识到我的调度程序正在激活具有调用功能的单独线程的新实例。


代码


主窗口

    public MainWindow()
    {
        InitializeComponent();

        //..deleteted irrelevent code..//

        //Activate Application Detection
        AppDetect_Infinite AI = new AppDetect_Infinite();
        Thread thread = new Thread(new ThreadStart(() => AI.run()));
        thread.Start();
    }

AppDetect_Infinite Window

public partial class AppDetect_Infinite : Window
{
    [DllImport("user32.dll")]
    static extern IntPtr GetActiveWindow();
    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll")]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
    public AppDetect_Infinite()
    {
        InitializeComponent();
    }
    public void run() {
            string newWindows = "";
        Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
        {
        while (true)
        {
        const int nChars = 256;
        StringBuilder Buff = new StringBuilder(nChars);
        IntPtr handle = GetForegroundWindow();
        if ((GetWindowText(handle, Buff, nChars) > 0) && (newWindows.Contains(Buff.ToString()) == false))
        {
            System.Windows.Forms.MessageBox.Show(Buff.ToString());
            if (newWindows.Length == 0)
                newWindows = Buff.ToString();
            else
                newWindows = newWindows + "|" + Buff.ToString();

            Process[] AllProcess = Process.GetProcesses();
            String title = Buff.ToString();

            foreach (Process pro in AllProcess)
            {
                if (title.Equals(pro.MainWindowTitle))
                {
                    try
                    {
                        string[] fn = pro.MainModule.FileName.ToString().Split('\\');
                        //MessageBox.Show(Buff.ToString() + " | " + fn[fn.Length - 1]);
                    }
                    catch { }
                }
            }
                }
            }
        }));
    }
}

任何想法如何激活这个单独的线程而不让它在我的主应用程序中给我一个旋转的蓝色死亡光环?我对所有建议持开放态度。

2 个答案:

答案 0 :(得分:1)

您正在通过新线程中的Dispatcher.BeginInvoke将调度程序安排到调度程序,但不要在此线程上运行调度程序。 换句话说,你需要以某种方式在这个新线程中运行消息循环。一种方法是在this.ShowDialog()中运行AppDetect_Infinite。 另一个只是Application.Run

编辑: ShowDialog无效。您的AppDetect_Infinite绑定到构造函数中的主线程。如果你想让它在另一个线程中运行 - 你应该首先在那里创建它。

在线程上创建线程并不是必需的。至少我不知道为什么要在Dispatcher.BeginInvoke

中的lambda中创建另一个线程

EDIT2: ...并且没有充分理由混合使用WPF和WinForms也不是一个好主意。

答案 1 :(得分:1)

您没有在另一个线程中执行代码,因为Dispatcher与主线程关联,来自MSDN:

Dispatcher.BeginInvoke

Executes a delegate asynchronously on the thread the Dispatcher is associated with.

如果你不想阻止主线程通过Thread或ThreadPool执行你的代码,不要调用dispatcher,否则它将在主线程上执行。