C# 如何让程序等待任务完成,然后在单击关闭按钮后退出
正如标题所示,如何让我的程序等待完成某件事情,然后在单击close按钮后退出 我必须确保一些重要任务已经完成,这样我才能让程序退出。但是我不知道怎么做 我试图创建一个这样的标志:C# 如何让程序等待任务完成,然后在单击关闭按钮后退出,c#,multithreading,C#,Multithreading,正如标题所示,如何让我的程序等待完成某件事情,然后在单击close按钮后退出 我必须确保一些重要任务已经完成,这样我才能让程序退出。但是我不知道怎么做 我试图创建一个这样的标志: public partial class MainForm : Form { public bool closeable = true; public MainForm() { InitializeComponent();
public partial class MainForm : Form
{
public bool closeable = true;
public MainForm()
{
InitializeComponent();
}
public setCloseable()
{
this.closeable = false;
}
}
在另一个线程中,当我的程序正在做一些非常重要的事情时,我在任务完成后将“closeable”设置为false,将closeable设置为true;
当使用按钮单击关闭按钮时,我使用以下代码:
private void MainForm_closing(object sender, FormClosingEventArgs e)
{
if (this.closeable == true)
{
Application.Exit();
}
}
这不起作用,因为如果使用时该值不为真,请单击“关闭”。然后程序将不会关闭
这条路对吗?我应该如何改进它或提出任何建议?您可以使用该属性。将其设置为true
将取消关闭表单
bool hasUserClickedClose = false;
private void MainForm_closing(object sender, FormClosingEventArgs e)
{
if (!this.closeable)
{
e.Cancel = true;
hasUserClickedClose = true;
}
}
然后在其他方法完成其任务之后
if(hasUserClickedClose)
{
this.closeable = true;
Application.Exit();
}
保持代码不变,但必须在关闭处理程序中将
FormClosingEventArgs.Cancel
分配给True
,以避免程序在不应该关闭时关闭
您应该在结束处理程序中添加一个计时器
,该计时器仅在您正在运行任务且任务尚未启动时启动。这个计时器每秒钟或五秒钟运行一次,或者任何你认为合适的时间。计时器的任务是检查任务是否已完成,如果已完成,它会将closeable
字段设置为true,并在程序中触发Close
事件
然后,您的FormClosing
事件将触发,查看closeable
是否为True
,然后它将不会将FormClosingEventArgs.Cancel
设置为True,并允许程序退出
Timer timer1 = null;
public MainForm()
{
InitializeComponent();
timer1 = new Timer();
timer1.Interval = (int)new TimeSpan(0, 0, 4).TotalMilliseconds;
timer1.Tick += (s, ev) => { timer1.Stop(); closeable = IsTaskDone(); Close(); };
}
public bool closeable = true;
public void setCloseable()
{
this.closeable = false;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.closeable == true)
{
Application.Exit();
}
else
{
timer1.Start();
e.Cancel = true;
}
}
private bool IsTaskDone()
{
// TODO: returns true if the task is completed
}
键盘输入法是正确的,我认为它也是最简单的。然而,我怀疑你在期待更聪明的东西 您可以创建一个特殊的单例类。在MainForm中使用“closeable”标志,而只需放置一个integer类型的“ImportantTaskScont” 每次重要任务启动时,您都应该递增该计数器,并在任务终止时递减该计数器 singleton模式简化了从任何地方对控制器实例的访问 现在,这里是诀窍:
// Winforms/WPF version
public sealed class CloseManager
{
private CloseManager(){}
private static CloseManager _instance;
public static CloseManager Instance
{
get
{
if (_instance == null) _instance = new CloseManager();
return _instance;
}
}
private static bool closeable;
private static int importantTasksCount;
public static void CloseRequest()
{
this.closeable = true;
}
public static void IncImportantTask()
{
this.importantTasksCount++;
}
public static void DecImportantTask()
{
this.importantTasksCount--;
if (this.closeable) Application.Exit();
}
}
您可以在
importantTask
任务中完成繁重的工作,但从用户的角度来看,这样做有点难看。根据你所说的你想要的,这应该是可行的:
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
this.importantTask= Task.Factory.StartNew(()=>{/*do your work*/});
}
private Task importantTask;
private async void MainForm_closing(object sender, FormClosingEventArgs e)
{
await importantTask;
}
}
你可以使用backgroundworker,也可以使用task和eventwaithandles。如何,你能给我一些演示吗?这里是backgroundworker,这里是eventwaithandles,你可以将TPL与WaitAll一起使用。所有这些只是让程序在有重要任务时无法关闭。我需要它在任务完成后退出!我以为这就是重点?您不希望应用程序在执行重要工作时关闭,但应在该任务完成时关闭。随着代码的运行,此任务完成后,应再次单击关闭!我不想再次单击“关闭”按钮。如果用户单击“关闭”按钮,然后在方法完成后检查此变量,您能否只设置一个变量?太好了,我怎么能不考虑计时器!哈哈,太好了,我想开始一个新的线程。但你解决了我的问题。想了很多!但请稍候,当使用“单击关闭”时,也可能发生这种情况。任务正在运行,当任务不幸完成时,新任务再次启动,更糟糕的是,当计时器检查可关闭项时,它为false,但当任务完成时,计时器未检查。。。。。。。。哇,一个糟糕的情况。我个人不喜欢计时器的方式,也因为计时器和窗口在没有正确管理的情况下可能会导致内存泄漏。让我们说,上面的一个是非常具体的情况下,但只是在案件有更多的窗口,你会得到一个痛苦…顺便说一句。现在我有另一个类。在这个类中,我想设置closeable而不使用新的MainForm如何实现?@JasonYang,我已经更新了我的代码示例。这将更好地观察新任务的启动。此外,您还可以缩短间隔。谢谢,但是这段代码很难阅读。而且重要的任务不仅仅是一项。因此,我认为这不是一个好的解决方案。但再次感谢为什么要使用单例模式?我建议使用单例模式,因为请求的函数是全局函数(即退出应用程序),并且很容易从应用程序中的任何位置访问。用户没有指定负责“重要”任务的人,因此单身者应该是相当中立的。此外,我不知道只有一个主窗体:一个应用程序可能打开多个窗口。你的代码似乎不是一个单例。你能再次编辑它吗?这个类或者至少计数器字段不应该是静态的吗?好吧,我明白了:我的示例提到了WPF,但在Winforms世界中没有什么不同。让我编辑源代码。。。