你可以使用
te.Join();
作为 Main 结束前的最后一行。这应该可以正常工作。
更详细的解释应该如何
当您启动一个 Windows 窗体应用程序时,您启动了一个 GUI/事件/主线程。在 winforms 库中的某处可视化如下所示的无限 while 循环
Queue<EventArgs> EventQueue = new Queue<EventArgs>();
while (!StopRequested) {
if (EventQueue.Any())
ProcessEvent(EventQueue.Dequeue());
Thread.CurrentThread.Sleep(100);
}
所有控件都在这个线程中创建,所有事件都在这个线程中触发。现在,由于您的代码中不存在此代码,因此获得 GUI/事件相关服务的唯一方法是发布到此 EventQueue
现在有了这个背景,让我们来看看你的情况。
引发和处理事件
一个表单/线程的引发和处理事件的工作方式与多个表单/线程的工作方式完全相同。请记住,引发事件只是发布到 EventQueue 的行为,并且事件处理程序的调用发生在 ProcessEvents 中
表单生命周期
在典型的 WinForms 应用程序中,您可以使用如下所示的行来告诉系统创建一个 EventQueue 并将其生命周期与表单的生命周期相关联。
Application.Run(new Form());
你可以使用
new Form().Show()
开始将事件泵入EventQueue,从而显示表单,但请记住,一旦您的应用程序的主线程到达Main 的末尾,EventLoop 将被突然终止。
因此关闭此表单将导致您的应用程序停止,反之亦然。
您的情况
我强烈建议您从主线程启动表单,然后在新线程上完成其他工作。我看到您将发件人用作int 和int[],这是一个问题。如果我需要实现相同的目标,以下是我将如何编写。我尽量保持它与您的样本相似
class Program {
static Form1 frm;
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
frm = new Form1();
frm.Test += TestEventHandler;
new Thread(new ThreadStart(DoAsyncProcessing)).Start();
Application.Run(frm);
}
static void DoAsyncProcessing() {
// async code goes here
Thread.Sleep(5000);
// raise the event
frm.RaiseTestEvent("Test Event Data");
}
static void TestEventHandler(object sender, TestEventArgs e) {
System.Diagnostics.Debug.WriteLine("Received test event with data: "
+ e.EventData);
}
}
public partial class Form1 : Form {
public event EventHandler<TestEventArgs> Test;
public Form1() {
InitializeComponent();
}
public void RaiseTestEvent(string eventData) {
var arg = new TestEventArgs() { EventData = eventData };
OnTest(arg);
}
protected virtual void OnTest(TestEventArgs e) {
EventHandler<TestEventArgs> handler = Test;
if (handler != null)
handler(this, e);
}
}
public class TestEventArgs : EventArgs {
public object EventData { get; set; }
}