C # Отмена асинхронного потока немедленно - PullRequest
1 голос
/ 23 ноября 2011

Я запускаю поток, когда нажимаю на кнопку запуска, которая запускает таймер задержки, а затем показывает диалог MessageBox. Сейчас я пытаюсь остановить этот поток, но я не могу найти для этого пути, кроме как добавить флаг, который будет препятствовать тому, чтобы поток отображал диалоговое окно messageBox, но не убивал поток. Буду признателен, если вы можете предложить способ убить поток.

Спасибо Моти

public partial class Form1 : Form
{
    public delegate void example();
    ThreadA threadA = null;

    public Form1()
    {
        InitializeComponent();
    }

    example ex;
    IAsyncResult result;
    private void button_Start_Click(object sender, EventArgs e)
    {
            ex = new example(start);//.BeginInvoke(null, null);
            result = ex.BeginInvoke(null, null);
    }

    private void button_Stop_Click(object sender, EventArgs e)
    {
        if (threadA != null)
            threadA = null;
    }

    private void start()
    {
        if (threadA == null)
        {
            threadA = new ThreadA();
            threadA.run();
        }
    }

}




class ThreadA
{
    //public event
    public Boolean flag = false;
    public void run()
    {
        Thread.Sleep(15000);
        MessageBox.Show("Ended");
    }
}

Ответы [ 2 ]

1 голос
/ 23 ноября 2011

Я бы использовал класс Task с CancellationTokenSource.

 CancellationTokenSource cts = new CancellationTokenSource();
 Task t = new Task(() => new ThreadA().run(cts.Token), cts.Token); 

  // Start
  t.Start();
  ShowMessageBox(cts)

Edit2: на ваш комментарий:

void ShowMessageBox(CancellationTokenSource cts)
{ 
    if(MessageBox.Show("StopThread",
    "Abort",MessageBoxButtons.YesNo,
     MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
    {
      cts.Cancel();
  }       
}
0 голосов
/ 23 ноября 2011

Использовать ManualResetEvent

class ThreadA
{
    ManualResetEvent _stopEvent = new ManualResetEvent(false);
    Thread _thread;

    public Boolean flag = false;
    public void run()
    {
        while (true)
        {
            if (_stopEvent.Wait(15000))
                return; // true = event is signaled. false = timeout

            //do some work
        }

        MessageBox.Show("Ended");
    }

    public void Start()
    {
        _stopEvent.Reset();
        _thread = new Thread(run);
        _thread.Start();
    }

    public void Stop()
    {
        _stopEvent.Set();
        _thread.Join();
        _thread = null;
    }
}

Однако я бы использовал Timer, если поток не будет работать все время.

...