产生一个新的线程来打开一个新窗口,并从不同的线程关闭 [英] Spawn a new thread to open a new window and close it from a different thread

查看:152
本文介绍了产生一个新的线程来打开一个新窗口,并从不同的线程关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我有C#code在不同的线程产卵一个新的窗口,这工作,但只要新的催生窗口打开,关闭和线头。如何将使它所以新的衍生窗口可从第一线程关闭?

Right now I have C# code to spawn a new window in a different thread, this works, but as soon as the new spawned window opens, it closes and the thread ends. How would I make it so the new spawned window can be closed from the first thread?

下面是一个产卵目前是如何工作的树:

Here is a "tree" of how the spawning currently works:

主线程结果
--Uses在主线程功能来启动另一种功能在单独的线程以打开瓦特窗口,使窗口中使用该线程

Main thread
--Uses a function in the main thread to start another function in a separate thread to open w window, causing the window to use that thread.

基本上我只想两个窗口都有自己的线程。并能够从第一窗​​口线程控制催生二级窗口

Basically I just want the two windows to each have their own thread. And be able to control the spawned secondary window from the first window thread.

推荐答案

这仅仅是一个简单的例子。这是一个有点比第一个我写的更加强劲。它通过使用P / Invoke消除现有的竞争条件。

This is just a quick example. It's a little more robust than the first one I wrote. It eliminates the existing race condition by using p/invoke.

更新仍然有竞争状态。这其中的的完善。

Updated Still had a race condition. This one should be perfect.

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

class MainUIThreadForm : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainUIThreadForm());
    }

    private IntPtr secondThreadFormHandle;

    public MainUIThreadForm()
    {
        Text = "First UI";
        Button button;
        Controls.Add(button = new Button { Name = "Start", Text = "Start second UI thread", AutoSize = true, Location = new Point(10, 10) });
        button.Click += (s, e) =>
        {
            if (secondThreadFormHandle == IntPtr.Zero)
            {
                Form form = new Form
                {
                    Text = "Second UI",
                    Location = new Point(Right, Top),
                    StartPosition = FormStartPosition.Manual,
                };
                form.HandleCreated += SecondFormHandleCreated;
                form.HandleDestroyed += SecondFormHandleDestroyed;
                form.RunInNewThread(false);
            }
        };
        Controls.Add(button = new Button { Name = "Stop", Text = "Stop second UI thread", AutoSize = true, Location = new Point(10, 40), Enabled = false });
        button.Click += (s, e) =>
        {
            if (secondThreadFormHandle != IntPtr.Zero)
                PostMessage(secondThreadFormHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
        };
    }

    void EnableStopButton(bool enabled)
    {
        if (InvokeRequired)
            BeginInvoke((Action)(() => EnableStopButton(enabled)));
        else
        {
            Control stopButton = Controls["Stop"];
            if (stopButton != null)
                stopButton.Enabled = enabled;
        }
    }

    void SecondFormHandleCreated(object sender, EventArgs e)
    {
        Control second = sender as Control;
        secondThreadFormHandle = second.Handle;
        second.HandleCreated -= SecondFormHandleCreated;
        EnableStopButton(true);
    }

    void SecondFormHandleDestroyed(object sender, EventArgs e)
    {
        Control second = sender as Control;
        secondThreadFormHandle = IntPtr.Zero;
        second.HandleDestroyed -= SecondFormHandleDestroyed;
        EnableStopButton(false);
    }

    const int WM_CLOSE = 0x0010;
    [DllImport("User32.dll")]
    extern static IntPtr PostMessage(IntPtr hWnd, int message, IntPtr wParam, IntPtr lParam);
}

internal static class FormExtensions
{
    private static void ApplicationRunProc(object state)
    {
        Application.Run(state as Form);
    }

    public static void RunInNewThread(this Form form, bool isBackground)
    {
        if (form == null)
            throw new ArgumentNullException("form");
        if (form.IsHandleCreated)
            throw new InvalidOperationException("Form is already running.");
        Thread thread = new Thread(ApplicationRunProc);
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = isBackground;
        thread.Start(form);
    }
}

下面是对子孙后代的第一个例子:

Here is the first example for posterity:

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

class MainUIThreadForm : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainUIThreadForm());
    }

    SecondUIThreadForm secondThreadForm;
    public MainUIThreadForm()
    {
        Text = "First UI";
        Button button;
        Controls.Add(button = new Button { Text = "Start second UI thread", AutoSize = true, Location = new Point(10, 10) });
        button.Click += (s, e) =>
            {
                if (secondThreadForm == null || !secondThreadForm.IsHandleCreated)
                    secondThreadForm = SecondUIThreadForm.Create();
            };
        Controls.Add(button = new Button { Text = "Stop second UI thread", AutoSize = true, Location = new Point(10, 40) });
        button.Click += (s, e) =>
        {
            if (secondThreadForm != null && secondThreadForm.IsHandleCreated)
                secondThreadForm.Invoke((Action)(() => secondThreadForm.Close()));
        };
    }
}

class SecondUIThreadForm : Form
{
    static void Main2(object state)
    {
        Application.Run((Form)state);
    }

    public static SecondUIThreadForm Create()
    {
        SecondUIThreadForm form = new SecondUIThreadForm();
        Thread thread = new Thread(Main2);
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start(form);
        return form;
    }

    public SecondUIThreadForm()
    {
        Text = "Second UI";
    }
}

这篇关于产生一个新的线程来打开一个新窗口,并从不同的线程关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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