我有两个C#winform(.NET 4.0)表单,每个表单连续运行单独但类似的自动化任务。它们是不同的流程/工作流程,但它们在项目中共享相同资源(方法,数据模型,程序集等)的操作方式相似。
两种表单都已完成,但现在我不确定如何运行程序,以便每个窗口在启动时打开并独立运行。部署后该程序将“永远在线”。
这看起来有点基础,但我的大多数开发经验都是Web应用程序。线程/等对我来说仍然有些陌生。我已经研究过,但我发现的大多数答案都与用户交互和顺序用例有关 - 这只是一个系统连续运行两个不同的进程,需要独立地与世界进行交互。
我发现的潜在解决方案可能涉及多线程,或者某种MDI,或者有些人建议使用DockPanelSuite(尽管处于超级企业环境中,下载第三方文件说起来容易做起来难)
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Rather than specifying frmOne or frmTwo,
// load both winforms and keep them running.
Application.Run(new frmOne());
}
}
答案 0 :(得分:30)
您可以创建一个新的ApplicationContext
来表示多个表单:
public class MultiFormContext : ApplicationContext
{
private int openForms;
public MultiFormContext(params Form[] forms)
{
openForms = forms.Length;
foreach (var form in forms)
{
form.FormClosed += (s, args) =>
{
//When we have closed the last of the "starting" forms,
//end the program.
if (Interlocked.Decrement(ref openForms) == 0)
ExitThread();
};
form.Show();
}
}
}
使用它你现在可以写:
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MultiFormContext(new Form1(), new Form2()));
答案 1 :(得分:9)
如果你真的需要两个窗口/表单在两个独立的UI线程上运行,你可以这样做:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var thread = new Thread(ThreadStart);
// allow UI with ApartmentState.STA though [STAThread] above should give that to you
thread.TrySetApartmentState(ApartmentState.STA);
thread.Start();
Application.Run(new frmOne());
}
private static void ThreadStart()
{
Application.Run(new frmTwo()); // <-- other form started on its own UI thread
}
}
答案 2 :(得分:1)
您不需要需要两个不同的进程,您只使用这两个进程,因为您希望拥有两个不同的表单,并且希望能够保持应用程序运行,直到两个表单都退出
依靠Form.Closed
事件机制。您可以添加一个事件处理程序,它允许您指定表单关闭时要执行的操作。例如。 两个表单关闭时退出应用程序。
public Form1()
{
InitializeComponent();
_form2 = new Form2();
_form2.Show(this);
this.Closed += Form1Closed;
_form2.Closed += Form2Closed;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
e.Cancel = true;
Hide();
Form1Closed(this, new EventArgs());
base.OnFormClosing(e);
}
private void Form1Closed(object sender, EventArgs eventArgs)
{
form1IsClosed = true;
TryExitApplication();
}
private void Form2Closed(object sender, EventArgs eventArgs)
{
_form2IsClosed = true;
TryExitApplication();
}
private void TryExitApplication()
{
if (form1IsClosed && _form2IsClosed)
{
Dispose();
Application.Exit();
}
}
请注意,这应该重构,以使其成为更好的解决方案。
<强>更新强>
Servy提供的评论使我修改了这个“应该是简单的解决方案”,指出他的解决方案比这个解决方案更好。由于我支持留下答案,我将使用此答案,我还将解决在寻求此解决方案时出现的问题:
Dispose
。