Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用on/off开关重复调用异步方法_C# - Fatal编程技术网

C# 如何使用on/off开关重复调用异步方法

C# 如何使用on/off开关重复调用异步方法,c#,C#,在WinForm应用程序中,我有一个后台进程的开/关开关。 单击后,程序将启动一个进程,并在完成后重新启动,直到您使用关闭开关 以下代码是出现多个问题的工作尝试 来自Damien_的不信者评论: 挂起线程,这意味着它们将永远存在,并通过递归实现循环,这很容易导致堆栈溢出 public partial class frmMain { Thread thread; bool isRunning = false; public frmMain() {

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

以下代码是出现多个问题的工作尝试

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

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

我正在尝试从这个工作解决方案切换到。

在BackGroundWorker出现的情况下实施您的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";
}
正确实施后,您的用户将看到如下内容:


问题是?@PeterBons,如何使用开/关开关重复调用异步方法?两个主要问题-挂起线程,这意味着它们永远存在,以及通过递归实现循环,这很容易导致堆栈溢出。不知道你现在的问题是什么。@Damien_,不信者,这是“让它工作”部分,我不知道如何正确编码,所以我做了这个丑陋的补丁。问题是我想实现一个正确的、干净的重复调用的方法,这正是我在原始代码中的评论。如果这还不清楚,请不要自己动手,也不要向我们索要代码。请告诉我。我提供了一个小例子,说明我试图实现什么,以及我目前是如何做到的。我没有提供一个不起作用的尝试,因为它可能会让人困惑,并且可能会因为打字错误或类似的X/Y问题而接近。