簡體   English   中英

C# 表單應用程序 - 單擊另一個按鈕即可停止正在進行的進程

[英]C# Form Application - Stop an ongoing process with a click of another button

是否可以通過在 Windows 表單應用程序中單擊按鈕來停止正在進行的進程?

  1. 例如,假設有 2 個按鈕,“開始”和“停止”
  2. 當您按下“開始”時,它將開始一個無限循環,打印從 1 到無窮大的數字。
  3. 當我按“停止”時,該過程應該在那一刻停止。
  4. 但問題是,我不能按“停止”按鈕,因為它不允許我,因為有一個正在進行的過程。

有沒有辦法克服這個問題?

我知道有一個叫做“MethodInvoker”的東西,但我不知道它是如何工作的,也不知道它是否與此相關。

    private bool keepRunning = true;

    public Form1()
    {
        InitializeComponent();
    }

    private void StartBtn_Click(object sender, EventArgs e)
    {
        var number = 1;
        while (keepRunning)
        {
            Thread.Sleep(1000);
            MesgeLabel.Text = "" + number++;
        }
    }

    private void StopBtn_Click(object sender, EventArgs e)
    {
        //Cannot even click this button
        keepRunning = false;
        //or
        Application.Exit();
    }

如果您產生了一個新進程,那么您可以調用 kill 方法。

Process myProcess = Process.Start("Notepad.exe")//starts new process
myProcess.Kill();// kills the process. save reference to myProcess and call kill on STOP button click

如果您已經啟動了新線程,則調用 abort 方法來停止線程。

Thread thread = new Thread(new ThreadStart(method)); 
thread.Start(); 
thread.Abort(); // terminates the thread. call abort on STOP button click

當您按下“開始”按鈕時,運行和打印數字的代碼將在 ui 線程上運行。 (根據您的解釋,我假設您所擁有的只是按鈕按下事件的消息處理程序,僅此而已。例如:未設置單獨的線程。)。

在 ui 線程上運行無限循環意味着您沒有更多時間來處理其他消息。 (負責處理 ui 消息的線程卡在無限循環中。)

因此,為了能夠按下“停止”按鈕,您需要在不同的線程或完全不同的進程中運行具有無限循環的代碼。 這就是 Arjun 想要告訴你的。 (如果您希望無限循環中的代碼從表單應用程序訪問資源,則需要一個線程。[線程在 forms 應用程序進程內。])

請注意:如果您創建一個線程並在該線程內運行您的數字打印代碼,這將不是 ui 線程。 因此,您將無法與 forms 控件進行交互,就像您在 ui 線程上一樣。 (即:嘗試設置 windows.text 以顯示您的數字很可能會引發異常。)

編輯1:

如果您需要與 UI 控件交互,從后台任務執行此操作會引發無效操作 -> 非法跨線程異常。 為了克服這一點,

檢查Control.InvokeRequired

if(myLabel.InvokeRequired)
    myLabel.Invoke(new Action(() => myLabel.Text = newText));
else
    myLabel.Text = newText;

您可以通過提供 CancellationToken 來啟動Task ,並在單擊停止按鈕時取消操作。

該任務將在另一個線程上執行無限循環,並且您的主線程(UI 線程)不應該受到影響並且應該可以訪問。

嘗試這個:

/*
    Please add these on top of your form class

    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
*/

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    CancellationTokenSource cancellationTokenSource;
    CancellationToken cancellationToken;

    private void CountToInfinity()
    {
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            Debug.WriteLine(new Random().Next());
        }
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        if (cancellationTokenSource == null)
        {
            cancellationTokenSource = new CancellationTokenSource();
            cancellationToken = cancellationTokenSource.Token;
            Task.Run((Action)CountToInfinity, cancellationToken);
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        if (cancellationTokenSource != null)
        {
            cancellationTokenSource.Cancel();
            cancellationTokenSource.Dispose();
            cancellationTokenSource = null;
        }
    }


}

暫無
暫無

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

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