I wrote a small program:

Thread1 thread:

 public void ExecuteCommandSync(string argument)
        {
            try
            {
                var procStartInfo = new System.Diagnostics.ProcessStartInfo("bbb.bat", argument);
                procStartInfo.RedirectStandardOutput = true;
                procStartInfo.UseShellExecute = false;
                procStartInfo.CreateNoWindow = true;
                procStartInfo.ErrorDialog = false;
                var proc = new System.Diagnostics.Process();
                proc.OutputDataReceived += (s, e) =>
                {
                    if (!string.IsNullOrEmpty(e.Data))
                    {
                        LogBox.BeginInvoke(new EventHandler(delegate { LogBox.AppendText(e.Data.ToString() + Environment.NewLine); }));
                        LogBox.BeginInvoke(new EventHandler(delegate { LogBox.ScrollToCaret(); }));
                    }
                };
               proc.StartInfo = procStartInfo;
               proc.Start();
               proc.BeginOutputReadLine();
               proc.WaitForExit();
            }
            catch (Exception objException)
            {
                Console.WriteLine("Error: " + objException.Message);
            }
        }

UI Thread:

var command = new Thread(() => ExecuteCommandSync(argument));
                command.Start();
                command.Join();
                while (!command.IsAlive)
                {
                    if (LogBox.Text.Contains("error code 0"))
                    { AddMessage("\r\n" + "Operation successful.\r\n", Color.DarkGreen, FontStyle.Bold); }
                    else
                    { AddMessage("\r\n" + "Operation unsuccessful.\r\n", Color.DarkRed, FontStyle.Bold); }
                    LogBox.ScrollToCaret();
                    path = null;
                    button1.Enabled = false;
                    break;
                }

The problem is that
Thread1 thread should be finished before the UI thread shows "operation successful/unsuccessful message"
With the code above, UI thread shows that message before thr results from Thread1 :(((((

How to make it in correct order?

Thx for help in advance!

Edited 4 Years Ago by VasquezPL

Ok, so you start be creating, starting and joining a thread. This is fine, the UI thread will not execute until "Thread1" finishes. However, in "Thread1" you are updating the LogBox with BeginInvoke(). This is of course correct(ish), since you cannot update controls on anything other then the UI thread. Now, BeginInvoke() runs on the UI thread, but does not block "Thread1". This means that "Thread1" will not wait for the LogBox to be updated.

So the question is: when will the UI get updated? Well, the UI thread is blocked until "Thread1" finishes executing. It also cannot be updated while the method in your code snippet is running. The actual invoke would not take place until control is returned to whatever method is managing the UI (this also rules out Invoke() as an option, as this would lead to a deadlock). So, it is guaranteed not to be set before your if statement.

The first and simplest solution is to not use a thread at all. Since you are blocking the UI thread anyways, threads are completely unnecessary here.

The advantage to using a separate thread with a UI, is to allow the UI to be active while some background work is taking place (if you don't, your UI becomes unresponsive and may stop displaying controls). This leads to the second solution, use a BackgroundWorker. You essentially use 3 events to complete some work:

  1. DoWork: in this event all of the work is handled by a second thread. From this event handler, you can call ReportProgress() which invokes the ProgressChanged event.
  2. ProgressChanged: this event allows you to modify the UI, as it is called in the UI thread while blocking the background worker thread.
  3. RunWorkerCompleted: this event is invoked on the UI thread when DoWork finishes. This allows you to make any final changes to the UI.

Note: with solution 2, your UI would remain active. This means the user can interact with the UI (change things, click things, etc...). If this is undesirable for certain controls, you would have to handle that in some way.

Hope that helps.

Thx for suggestions - I will ry to implict them today..I will update this "thread" :P soon :)

and I really need to use threads...My program is an frontend application for the program which is running in cmd...Sometimes it's running for 2-5 minutes and then my UI is unresponsive. I want to avoid that...

This article has been dead for over six months. Start a new discussion instead.