How to avoid freezing of GUI?

15,969

Solution 1

You could do something like this:

toolStripStatusLabel1.Text = " Device Testing...";
positive = false;
clearsensors_gui();
datarec = false;
cmd = 04;

BackgroundWorker worker = new BackgroundWorker();

worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
    // Will be run on background thread
    args.Result = serialport_FT(0, 1);
};

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    bool result = (bool)args.Result;

    if (result)
    {
        // Do your UI updates here
    }
};

worker.RunWorkerAsync();

One improvement could be to combine datarec and rec_data as a Tuple in args.Result.

Solution 2

In the background worker you use the DoWork event.

worker.DoWork += new DoWorkEventHandler(yourEventHandler); 

void yourEventHandler(object sender, DoWorkEventArgs e)
{
//your work here
}

Solution 3

As you are using WinForms, here is a great MSDN article to get you started with using multiple threads in an application: Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads

The article is 'a few days old', but the principles remain absolutely valid today.

If you are working in a .NET 4.x version, you can also use the Task Parallel Library to make working with multiple threads easier.

The upcoming .NET 4.5 also offers the even more comfortable await and asyc keywords: Asynchronous Programming with Async and Await.

Share:
15,969
pdthekd
Author by

pdthekd

Updated on July 14, 2022

Comments

  • pdthekd
    pdthekd almost 2 years

    i have a code which is like this :

    private void testToolStripMenuItem_Click(object sender, EventArgs e)
    {
        toolStripStatusLabel1.Text = " Device Testing...";
    
        positive = false;
    
        clearsensors_gui();
        datarec = false;
        cmd = 04;
        datarec = serialport_FT(0, 1);
    
        if (datarec)
        {
            char ab = Convert.ToChar(rec_data[1]);
            //MessageBox.Show("\n" + ab + "\n");
            int cab = Convert.ToInt16(ab);
            int cabc1 = cab & 1;
            int cabc2 = cab & 2;
            int cabc3 = cab & 4;
            int cabc4 = cab & 8;
            int cabc5 = cab & 16;
            int cabc6 = cab & 32;
    
            if (cabc1 == 1)
                ovalShape1.FillColor = Color.Green;
            else
                ovalShape1.FillColor = Color.Red;
    
            if (cabc2 == 2)
                ovalShape2.FillColor = Color.Green;
            else
                ovalShape2.FillColor = Color.Red;
    
            if (cabc3 == 4)
                ovalShape3.FillColor = Color.Green;
            else
                ovalShape3.FillColor = Color.Red;
    
            if (cabc4 == 8)
                ovalShape4.FillColor = Color.Green;
            else
                ovalShape4.FillColor = Color.Red;
    
            if (cabc5 == 16)
                ovalShape5.FillColor = Color.Green;
            else
                ovalShape5.FillColor = Color.Red;
    
            if (cabc6 == 32)
                ovalShape6.FillColor = Color.Green;
            else
                ovalShape6.FillColor = Color.Red;
    
            toolStripStatusLabel1.Text = " Device Tested";
        }
        else
        {
            toolStripStatusLabel1.Text = "Try Again or Communication With Device Failure....";
        }
    }
    

    the above code is to read a the sensors i.e datarec = serialport_FT(0, 1); function provides me a sensor output at the GUI side which'll be later depicted with red\green ovalShapeX(1-6)

    Question: datarec = serialport_FT(0, 1); this function takes liltime and so the GUI freezes till that time how to avoid this?

    i tried using background worker but didn't get where to put this whole process also encountered with cross-threaded operation error when it goes to ovalShape and changing its properties.

    I'm not getting what part of the function to be used in the background and where and when to get back to the 1st thread

    please help me to use backgroundworker or use invoke if i have to use Threading

  • pdthekd
    pdthekd almost 12 years
    thank you...tried this... i did not get any error this time but the UI din get updtated. I put the block: if(datatarec){...} under if(result){...}. What am i doing wrong?
  • ekholm
    ekholm almost 12 years
    Did you check that serialport_FT returned true and that result is true?
  • pdthekd
    pdthekd almost 12 years
    yes result is true... so after that i call another function which has lines under if(datarec){...} [in question post] ovalShapesX[1-6] aren't updating neither giving me exceptions nor errors
  • ekholm
    ekholm almost 12 years
    Hmm... And the data looks ok I pressume? Did the UI stuff work before? Is the text field updated?
  • pdthekd
    pdthekd almost 12 years
    data is ok ,used toolStripStatusLabel1.Text = "tested"; after the function is done calling, which is displayed. the code which i have posted above is a working 1 except for a small freeze point in while executing datarec= serial_FT(0,1); so i wanted to use background worker now
  • ekholm
    ekholm almost 12 years
    So the label is updated, but not the shapes? Maybe they need a Refresh()
  • pdthekd
    pdthekd almost 12 years
    i don get it ... can u please be little more elaborate?
  • ekholm
    ekholm almost 12 years
    Can't see what's wrong here. In RunWorkerCompleted you are back on the UI thread, so it shouldn't be a problem. You have set ovalShapeX.FillStyle = FillStyle.Solid? Could you post your current code?
  • pdthekd
    pdthekd almost 12 years
    thaks man .... ovalShapeX.FillStyle = FillStyle.Solid , i had missed this while writing the function again with backgroundworker... Thank u loads