Search code examples
c#formssessionoutlookbackgroundworker

C# BackgroundWorker Completed Called Way Before Completion


I have been trying to work out why my background worker is 'finishing' its work when there is still a lot for it to do. I am actually in the process of refactoring the code for this app, so it did work in the past, but now I am unable to figure out what has gone wrong.

Specifically, the app should open Outlook and then perform a few checks. However, the background worker exits straight after Outlook is opened for no apparent reason (as you will se below there is still plenty of processing to be done).

This appears to be happening early on in the Start() method, directly after calling Process.Start() on Outlook.exe.

The code runs in this order:

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++;
            }
        }
    }

As you can see from the comment, the backgroundworder is calling RunWorkerCompleted way before the Reset() method has finished executing.

Below are the other methods called (kill, logoff, start):

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

Does anyone have any idea what is going on here? It is driving me crazy!

Many thanks

Update

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

Solution

  • This is probably because of an exception being thrown from within the start method.

    You may either add a try / catch block all around this method and handle the error from within the catch, or check in the RunWorkerCompleted method if an exception occurred :

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