簡體   English   中英

停止長時間運行的事件

[英]Stop long running events

我有一個由另一個表單 Form1 打開的以下表單 Form3,當關閉 Form1 時,它會重新打開。

問題是當我關閉 Form3 時,DoSomething 在表單關閉后繼續運行。

我知道我可以將 DoSomething 變成一個線程並設置 IsBackground = true 但還有另一種方法可以在表單關閉時停止所有進程。

此代碼只是示例,用於說明。

   public partial class Form3 : Form
    {

    public Form3()
    {
        InitializeComponent();
    }
    private void DoSomething()
    {
        int i = 0;
        while(true)
        {
            if (!this.IsDisposed)
            {
                Application.DoEvents();
                i++;
                Thread.Sleep(10);
                label1.Text = i.ToString();
                dataGridView1.Rows.Add();
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void Form3_FormClosed(object sender, FormClosedEventArgs e)
    {
        this.Dispose();
        Form1.Default.Show();
    }

}

你永遠不會突破 while(true)。 您應該在 IsDisposed 為 true 時中斷循環,將 while 循環更改為 while(!IsDisposed),或者存儲使用確定何時中斷循環的類級別變量。

我可能會選擇后者,因為它給了你更多的控制權。

public partial class Form3 : Form
{
    volatile bool clDoSomething;

    public Form3()
    {
        InitializeComponent();
    }
    private void DoSomething()
    {
        int i = 0;
        clDoSomething = true;
        while(clDoSomething)
        {
            Application.DoEvents();
            ++i;
            Thread.Sleep(10);
            label1.Text = i.ToString();
            dataGridView1.Rows.Add();
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void Form3_FormClosed(object sender, FormClosedEventArgs e)
    {
        clDoSomething = false;
        Form1.Default.Show();
    }

}

你的基本方法有缺陷。

首先,應避免使用Application.DoEvents,除非您確定確實需要它並且正確使用它。 您在這里不需要它,並且您沒有正確使用它。

你真正需要的是一個Timer

private Timer timer = new Timer();
private int count = 0;
public Form3()
{
    InitializeComponent();

    timer.Tick += timer_Tick;
    timer.Interval = 10;

    //when the form is closed stop the timer.
    FormClosed += (_, args) => timer.Stop();
}

private void button1_Click(object sender, EventArgs e)
{
    count = 0;
    timer.Start();
}

private void timer_Tick(object sender, EventArgs e)
{
    count++;
    label1.Text = count.ToString();
    dataGridView1.Rows.Add();
}

創建Form時,配置Timer 滴答事件與間隔一起設置。 滴答事件看起來類似於你的DoSomething方法; 它將涉及每 10 秒從 UI 線程運行一些代碼,同時保持 UI 響應。 當表單關閉時,只需停止計時器,它將停止觸發這些事件。

另請注意,在此示例中,多次按下按鈕只會重置計時器和計數,它最終不會創建兩個循環,每個循環每 10 毫秒觸發一次。

根據需要覆蓋this.Dispose()this.Close()並手動this.Close() DoSomething() 。

感謝 cdhowie 的建議和所有其他人的投入。 將 DoEvents 修剪到最后並添加 IsDipsosed 解決了我的問題。

public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
    }
    private void DoSomething()
    {
        int i = 0;
        while ((true) && !this.IsDisposed)
        {
                i++;
                Thread.Sleep(10);
                label1.Text = i.ToString();
                dataGridView1.Rows.Add();
                Application.DoEvents();
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void Form3_FormClosed(object sender, FormClosedEventArgs e)
    {
        Form1.Default.Show();
    }

}

嘗試在 FormClosing 事件中添加此指令: System.Diagnostics.Process.GetCurrentProcess().Kill();

有點像這樣:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    System.Diagnostics.Process.GetCurrentProcess().Kill();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM