Today's Tip
---------------
If you've decided to handle certain things in a thread--like download a file or process something or scan something--and would like to be able to display Windows Form stuff about the progress or information being found within the thread... here's how to do it.
Problem: You want to avoid use-collisions and other race conditions between threads so your program doesn't explode. Adding something to a Windows Form object, like a ListView, requires your thread to be able to safely take control of the object's properties and methods.
Solution: You'll need to be able to create what is called a delegate to handle accessing your Form object's methods and properties. A delegate is a function-pointer and as such allows you to set up virtual calls to methods and properties so you can pass the buck a bit if the object is in use.
Full disclosure about Delegates:
http://msdn.microsoft.com/en-us/library/aa288459(VS.71).aspx
Solution, part 2:
Full disclosure about Invoke and InvokeRequired:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke(VS.71).aspx and
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx
The code looks like this:
// delegate defines our function pointer
delegate void AddItemToListBoxCallback(ref ListBox LB, string item);
// the function, defined below, matches the function pointer
// for return type as well as what we pass to it
private void AddItemToListBox(ref ListBox LB, string item)
{
if (LB.InvokeRequired)
{
AddItemToListBoxCallback d
= new addItemToListBoxCallback(AddItemToListBox);
this.Invoke(d, new object[] { LB, item });
}
else
{
LB.Items.Add(item);
}
}
You can apply this to any Windows Form object that is compatible with the Control method Invoke and of course has the InvokeRequired property. That covers almost all Form objects.
Quick breakdown:
AddItemToListBoxCallback and AddItemToListBox are names for the delegate and it's callback that I just made up; they're now my names for the function pointer
Variables passed to function / pointer: You can pass anything to the function / delegate, just like you would to any function
To use the above delegate you'd do something like this:
private void MyThread()
{
//... doing stuff ...
AddItemToListBox(ref myListBoxObject, myStringObject);
}
Keeping in mind that myListBoxObject is a ListBox object on your Form and that myStringObject is some string you defined. That's it for today's tip.
No comments:
Post a Comment