Home > Back-end >  "Please Wait" Window running in a separate Thread
"Please Wait" Window running in a separate Thread

Time:06-13

Multi-threading is a concept I am attempting to understand. I Am simply trying to create a "Working Please Wait" window with a Text message update as to the progress.

I cannot seem to Send a Message back to that thread to update the text message.

Here is how I am Starting my Thread:

frmProcessing Fp;

Thread FpThread = new Thread(() => {
    Fp= new frmProcessing();
    Fp.Tital("Building Database");
    Fp.Working("Clearing Old Data...");
    Fp.ShowDialog();
});

FpThread.SetApartmentState(ApartmentState.STA);
FpThread.Start();   

Attempting to run this function from the Thread preforming the updating action(original thread):

Fp.Working("new message");

I attempted this:

Fp.Invoke(new Action(() => {
    Fp.Working("new message");
}));

I get this error:

'Fp' is not null here.
CS0165:Use of unassigned local variable 'fp'

CodePudding user response:

Anyone Finding this Post. What fixed my problem was 3 parts. setting the NewForm to Null.

frmProcessing Fp;

now

frmProcessing Fp=null;

using BeginInvoke() functions on the Form running in the separate thread. Not from the function trying to access the form.

public void Working(string Working) // function on form running in new thread
        {

          BeginInvoke(new Action(() =>  lblProcess.Text = Working));
        
        }

More Code can be added to test to see if the message is coming from another thread, to be more complete.

Access to the methods and functions of the form in the new thread takes some time to start, so in my case I delayed accessing the forms methods for about 1 second by

threading.sleep(1000);

There might be Better ways to accomplish this task. But it works for me.

CodePudding user response:

Based on our conversation, here's one of many ways achieve that outcome. (In other words, this is how I personally do this kind of thing.)

public partial class MainForm : Form
{
    private void buttonModal_Click(object sender, EventArgs e)
    {
        var modal = new Progress();

        // Start a worker task to perform the
        // SQL updates and reset the application.
        Task.Run(() => 
        {
            for (int i = 0; i < 100; i  )
            {
                // Block on the thread doing the updating.
                // What you do here is up to you. This just
                // simulates work that takes some amount of time.
                Task.Delay(25).Wait();

                modal.SetProgress(i);
            }
            Invoke((MethodInvoker)delegate{ modal.Dispose(); });
        });

        // The modal dialog will prevent user interaction,
        // effectively locking user out until the update completes.
        modal.ShowDialog();
    }
}

Progress dialog with no title bar

where...

public partial class Progress : Form
{
    public void SetProgress(int i)
    {
        if (IsHandleCreated)    // Avoid potential race condition
        {
            Invoke((MethodInvoker)delegate { progressBar1.Value = i; });
        }
    }

    // This is probably in Progress.Designer.cs file
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // A debug message to confirm that this dialog is getting disposed.
            Debug.WriteLine("Progress dialog is now Disposing");
            if (components != null)
            {
                components.Dispose();
            }
        }
        base.Dispose(disposing);
    }
}
  • Related