如何使用开/关开关重复调用异步方法

时间:2018-01-02 10:46:27

标签: c#

在WinForm应用程序中,我有一个用于后台进程的On / Off开关 单击时,程序启动一个过程并在完成后重新启动,直到您使用关闭开关。

以下代码是有多个问题的工作尝试。

来自Damien_The_Unbeliever评论: 挂起线程意味着它们永远存在,并通过递归实现循环,这很容易导致堆栈溢出。

public partial class frmMain
{
    Thread thread;
    bool isRunning = false;

    public frmMain()
    {
        InitializeComponent();
    }

    private void OnOffSwitch_Click(object sender, EventArgs e)
    {
        if (!isRunning)
        {
            btnSwitch.Text = "Stop";
            isRunning = true;

            thread = new Thread(doLoop);
            thread.IsBackground = true;
            thread.Start();
        }
        else
        {
            if (thread.IsAlive)
                thread.Suspend();

            btnSwitch.Text = "Start";
            isRunning = false;
        }
    }

    public void doLoop()
    {
        ClearScreenLogic.Run();

        if (AutoReconnect)
            ReconnectLogic.Run();
        // Etc..

        doLoop();
    }

我正在尝试从此工作解决方案切换到background worker

1 个答案:

答案 0 :(得分:2)

在BackGroundWorker的DoWork事件中实施您的doLoop,并确保您处理取消。确保将backgroundworker的属性设置为WorkerReportprogress和WorkerSupportCancellation为true;

这就是你需要的:

private void button1_Click(object sender, EventArgs e)
{
    // on and off
    if (backgroundWorker1.IsBusy)
    {
        // cancel if we have not already done so
        if (!backgroundWorker1.CancellationPending)
        {
            backgroundWorker1.CancelAsync();
        }
    }
    else
    {
        // start the background work
        button1.BackColor = Color.Yellow;
        backgroundWorker1.RunWorkerAsync();
    }
}

// this runs on a background thread
// do not do stuff with the UI here
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    int progress = 0;
    // stop looping if cancellation is requested
    while (!backgroundWorker1.CancellationPending)
    {
        // make it nice
        backgroundWorker1.ReportProgress(progress);

        ClearScreenLogic.Run();

        if (AutoReconnect)
            ReconnectLogic.Run();
        // Etc..

        progress++; // for feedback
    }
}

// tell the use something is going on, this runs on the UI thread
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    label1.Text = e.ProgressPercentage.ToString();
}

// we're done, tell the user so
// this runs on the UI thread 
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    button1.BackColor = Color.Green;
    label1.Text = "cancelled";
}

正确实施后,您的用户会看到以下内容:

enter image description here