C# BackgroundWorker 在完成之前完成调用方式

C# BackgroundWorker Completed Called Way Before Completion

我一直在努力弄清楚为什么我的后台工作人员 'finishing' 在它还有很多工作要做的时候工作。我实际上正在重构这个应用程序的代码,所以它过去确实有效,但现在我无法弄清楚哪里出了问题。

具体而言,该应用应打开 Outlook,然后执行一些检查。但是,后台工作人员在打开 Outlook 后立即退出,原因不明(正如您将在下面看到的那样,仍有大量处理工作要做)。

这似乎发生在 Start() 方法的早期,直接在 Outlook.exe 上调用 Process.Start() 之后。

代码按以下顺序运行:

calling the background worker - this was the user's choice from a radio set

....
        else if (radioButton5.Checked == true)
        {
            textBox1.Text = "Please wait while your session restarts";
            pageControl1.SelectedIndex = 10;

            backgroundReset.RunWorkerAsync();
        }

The do-work method

    public void backgroundReset_DoWork(object sender, DoWorkEventArgs e)
    {
        backgroundReset.WorkerSupportsCancellation = true;

        Session.Reset();
    }

the reset session method starts by killing the current session ...

    public static void Reset()
    {
        KillSession();

        System.Threading.Thread.Sleep(5000);

        Start();

        // THE BACKGROUNDWORKER EXITS BEFORE HERE!

        if (IsLoggedIn() == false)
        {
            return;
        }
        else
        {
            // Make sure Lync is open before finishing the process ...
            var j = 0;

            GetSession(Init.servers);

            j = 0;
            var checker = false;

            checker = ProcessHandler.CheckRunning("lync.exe");

            while (checker == false)
            {
                if (j == 100)
                {
                    break;
                }
                Thread.Sleep(500);
                checker = ProcessHandler.CheckRunning("lync.exe");
                j++;
            }
        }
    }

正如您从评论中看到的,backgroundworder 在 Reset() 方法完成执行之前调用了 RunWorkerCompleted 方法。

下面是调用的其他方法(终止、注销、启动):

KillSession logs the session of and then makes sure it is logged off

    private static void KillSession()
    {
        if (sessionId != null)
        {
            LogOff();

            for (int i = 0; i < 150; i++)
            {
                if (IsLoggedIn() == true)
                {
                    Thread.Sleep(500);
                }
                else
                {
                    break;
                }
            }
        }
    }

LogOff sends a Cmd command to log off the current session

    public static void LogOff()
    {
        string strCmdIn = "/C LOGOFF " + sessionId + " /SERVER:" + serverName;
        Cmd.Exec(strCmdIn);
    }

Start() Simply opens Outlook, causing a Citrix session to also start. The app is definitely launching Outlook, but after that it doesn't reach either of the for statements - the BackgroundWorker just exits.

    public static void Start()
    {
        Process.Start(appDataCitrix + "Outlook.exe");

        for (int i = 0; i < 15; i++)
        {

            if (IsLoggedIn2() == false)
            {
                Thread.Sleep(1000);
            }
            else
            {
                break;
            }
        }

        if (IsLoggedIn2() == false)
        {
            Process.Start(appDataCitrix + "Outlook.exe");

            for (int i = 0; i < 10; i++)
            {
                if (IsLoggedIn2() == false)
                {
                    Thread.Sleep(1000);
                }
                else
                {
                    break;
                }
            }
        }
    }

有人知道这里发生了什么吗?这让我发疯!

非常感谢

更新

The RunWorkerCompleted Method: As far as my understanding goes, this has no baring on when the process will finish.

    public void backgroundReset_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (Session.IsLoggedIn())
        {
            btnFailFinish.Visible = true;
            label10.Text = Session.serverName;
            pageControl1.SelectedIndex = 3;
        }
        else
        {
            pageControl1.SelectedIndex = 10;
            pictureBox2.Visible = false;

            textBox1.Text = "Double-click Outlook on your desktop to launch a new session.";
            textBox15.Text = "Once you have done this please click Finish.";
            pictureBox9.Visible = true;
        }
    }

这可能是因为 start 方法中抛出了异常。

您可以在该方法周围添加一个 try / catch 块并从 catch 中处理错误,或者如果发生异常则检查 RunWorkerCompleted 方法:

    private void RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            // handle your exception here
        }
    }