如何让程序等待任务完成,然后单击关闭按钮后退出

时间:2013-07-28 13:54:08

标签: c# multithreading

如标题所示,如何让我的程序等待完成某些操作然后在单击关闭按钮后退出。

我必须确保完成一些重要的任务,这样我才能让程序退出。但我不知道该怎么做。

我试图创建一个这样的标志:

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();
        }
    }

这不起作用,因为如果使用点击关闭时该值不为真,那么程序将不会关闭。

这样对吗?我该如何改进或提出任何建议?

4 个答案:

答案 0 :(得分:0)

您可以使用Cancel属性。将其设置为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();
}

答案 1 :(得分:0)

保持您的代码不变,但您必须在结算处理程序中将FormClosingEventArgs.Cancel分配给True,以避免程序在不应该关闭的情况下关闭。

您应该添加的内容是关闭处理程序中的Timer,只有在您运行任务时才会启动,如果它尚未启动。这个计时器每隔一秒钟或五秒钟运行一次,或者你认为是一个很好的数量。计时器的工作是检查您的任务是否已完成,如果已完成,则会将closeable字段设置为true并触发程序中的Close事件。

然后,您的FormClosing事件将会触发,看到closeableTrue,然后不会将FormClosingEventArgs.Cancel设置为true,并允许程序退出。< / p>

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
}

答案 2 :(得分:0)

KeyboardP方式是正确的,我认为它也是最简单的。但是,我的怀疑是你期待更聪明的东西。

您可以创建一个特殊的单例类。而不是在MainForm中有“可关闭”标志,只需放置一个整数类型的“importantTasksCount”。

每次重要任务开始时,都应该递增该计数器,并在任务终止后递减计数器。

单例模式简化了从任何地方对控制器实例的访问。

现在,这就是诀窍:

// 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();
  }

}

答案 3 :(得分:0)

你可以在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;
    }
}