【问题标题】:Creating and showing a WindowsForm from another Thread in another class - C# [closed]从另一个类中的另一个线程创建和显示 WindowsForm - C# [关闭]
【发布时间】:2021-05-04 13:18:37
【问题描述】:

首先:我知道这个问题已经被问过很多次了,但我确实在这个问题上停滞了几个小时,并且我没有成功地将我发现的不同解决方案应用到我的问题。

我有一个这样的课程:

class Program
{
    private static UDProtocol MyUdp;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        MyUdp = new UDProtocol();
        MyUdp.Start();
        Application.Run();
    }
}

还有一个类 UDProtocol,我将其简化如下:

class UDProtocol
{
    UdpMe = new UdpClient(11000);

    public void Start()
    {
        new Thread(() =>
        {
            CreateNewForm();

        }).Start();
     }

    public void CreateNewForm()
    {
        //Form f1 = new Form()
        //f1.Show()
    }
  }

当我这样做时(使用 CreateNewForm 中的 cmets),我显示了我的表单,但它上面的控件都是透明的,如下所示:

我认为这是因为尝试在不同的线程中创建一个 from,我很确定我应该使用 Invoke,但我真的不知道该怎么做。

谢谢

编辑:解决方案

Application.Run(new Form());

在线程中添加这个可以解决问题。表格显示正确

【问题讨论】:

  • 看起来与线程无关,表单是在单个线程上创建和访问的。我不明白,你想每毫秒创建一个新表单??
  • @Charlieface 我明白了,不,当我简化代码以便它专门针对问题可读时,这是一个错误,我将对其进行编辑。
  • WPF 和 Winforms 控件必须从 STA 线程(在本例中为应用程序的主线程)进行管理,如果您想从其他线程引发新的 Winforms 控件/表单/事件,您应该使用调度员。
  • 这能回答你的问题吗? How to start a UI thread in C#

标签: c# multithreading winforms class invoke


【解决方案1】:

UDProtocol 对象应生成自定义Form 可用于向用户显示信息的事件。

class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        MyForm f1 = new MyForm();
        Application.Run(f1);
    }
}

public class UDProtocol {

    public event EventHandler SomeEvent;

    Thread tRead = null;
    public void Start() {
        // some internal thread starts
        if (tRead != null)
            throw new Exception("Already started.");

        tRead = new Thread(() => {
            while (true) {
                Thread.Sleep(1000);
                if (SomeEvent != null)
                    SomeEvent(this, EventArgs.Empty);
            }
        });
        tRead.IsBackground = true;
        tRead.Name = "UDProtocol.Read";
        tRead.Start();
    }
}

public class MyForm : Form {
    UDProtocol myUDP = new UDProtocol();

    public MyForm() {
        myUDP.SomeEvent += udp_SomeEvent;
    }

    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        myUDP.Start();
    }

    void udp_SomeEvent(object sender, EventArgs e) {
        this.BeginInvoke((Action) delegate {
            MessageBox.Show(this, "Some event happened in the UDP object.", "UDP Event");
        });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 2015-03-07
    • 1970-01-01
    • 2020-10-15
    相关资源
    最近更新 更多