Sunday, March 10, 2013

Control accessed from a thread other than the thread it was created on

Share/Save/Bookmark

BackgroundWorker and some basics around it.

Never thought i would get a chance to work with win forms. Here i am dancing with it.
I think its time for me to learn some basics about it.
I developed the app but its hanging while its working i.e executing the lengthy code.
I would not worry about it much but then the running information that i'm displaying on the form is not getting displayed due to it.

So what's the solution? BackgroundWorker
Yes, App gets hung as the entire operation was running in the same thread of the process.
so to avoid it a new thread must be spawn where the operations should run asynchronously.
Instead of cracking my head on spawning threads and handling them, .Net framework already
have a Class BackgroundWorker that supports this with all necessary events.

Here it is how i used it
BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.WorkerSupportsCancellation = true;
bgWorker.DoWork += DoWork;
// run the worker in async mode to avoid the app running smoothly without hanging
bgWorker.RunWorkerAsync();

public void DoWork(object sender,DoWorkEventArgs args)
{
//time consuming operations go here
}

That makes the app run cool but brought another issue
Cross-thread operation not valid: Control 'control1' accessed from a thread other than the thread it was created on
So i have to use the below delegate methods to access the objects that are created in a
thread different from current.Be aware that delegate can set only properties of the object
but cannot call any methods on it.

 delegate void SetControlValueCallback(Control oControl, string propName, object propValue);
        private void SetControlPropertyValue(Control oControl, string propName, object propValue)
        {
            if (oControl.InvokeRequired)
            {
                SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue);
                oControl.Invoke(d, new object[] { oControl, propName, propValue });
            }
            else
            {
                Type t = oControl.GetType();
                PropertyInfo[] props = t.GetProperties();
                foreach (PropertyInfo p in props)
                {
                    if (p.Name.ToUpper() == propName.ToUpper())
                    {
                        // append the data
                        //string existingValue = p.GetValue(oControl, propValue).ToString(); ;
                        p.SetValue(oControl, propValue, null);
                    }
                }
            }
        }




Subscribe

No comments:

Post a Comment