C# multi-thread approach in GUI
I'm developing a small app. Need your help.
I have a table of 10 columns. Say, i select 5 rows in a list view. I take all the values of col_1, in a list, pass it to a method.
If all values are equal, set combo_box1 value = "equal" else value = "not equal".
Current Approach:
I have 10 lists ( seems pretty lame... isn't it? i had asked a ques regarding this...), one for each col.
10 calls to the method that checks for equality of values, each for one list. Subsequently, set the combo box's(10 combo boxes) values.
If i have say 100 records, i guess the time taken will increase. So, i thought of implementing threads.
Effort Put:
I have used the this.Invoke(new Delegate...) approach for a thread which tries to access a control of Main thread. It works fine. I tried to manipulate this according to my needs. Couldn't do so. Please help me out guys.
[EDIT]
the main culprit was the image comparison... its taking awfully long time to finish... below is the code... i'm storing all the image(say col no 3) of say 10 rows in a list...
// other stuffs [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)] private static extern int memcmp(IntPtr b1, IntPtr b2, long count);
// create a list of images MemoryStream imageStream = new MemoryStream(tempImage.Data.Data); Bitmap artCoverImage = new Bitmap(imageStream); // culprit ? artCoverList.Add(artCoverImage);
// call the method CheckIfEqual(artCoverList) // culprit ?
// THE method private void CheckIfEqual(artCoverList) { Bitmap tempBitMap = artCoverList[0];
foreach开发者_开发技巧 (Bitmap bmp in artCoverList) { if (bmp == null) return false; if (bmp.Size != tempBitMap.Size) return false; var bd1 = tempBitMap.LockBits(new Rectangle(new Point(0, 0), tempBitMap.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr bd1scan0 = bd1.Scan0; int stride = bd1.Stride; long len = stride * tempBitMap.Height; var bd2 = bmp.LockBits(new Rectangle(new Point(0, 0), bmp.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr bd2scan0 = bd2.Scan0; returnValue = memcmp(bd1scan0, bd2scan0, len) == 0; bmp.UnlockBits(bd2); tempBitMap.UnlockBits(bd1); } }
I had spent a whole day to get this part image comparison working... i think the part where it converts mem stream to bmp is the culprit...
[EDIT 2]
guys...need your help... any idea... how to compare a list of images... other than above...
Thanks,
Dev
I would say that instead of using Invoke, check out BackgroundWorker
. It has callback events that automatically run on the main thread, so it makes updating your UI when you're done easier, so as to avoid cross thread UI exceptions.
BackgroundWorker worker = new BackgroundWorker();
worker.RunWorkerCompleted += (s, e) => updateUI();
worker.DoWork += (s, e) => longProcess();
worker.RunWorkerAsync();
Implementing a threaded design has its own overhead and adds complexity. You really only want to consider moving to a threaded model if performance is poor enough to warrant the added complexity.
If you have 100 rows and you are checking equality of 10 columns, then you're doing 1000 equality checks. Depending on the implementation, this should be a trivial operation with negligible performance ramifications.
Consider profiling your application to see if there is a performance issue.
EDIT
Based on your findings (that image comparison is the culprit), you may want to consider using a simple checksum comparison against the respective image byte arrays.
Here is an example of how to do so: http://www.dreamincode.net/code/snippet2859.htm
Note: MD5 is sufficient in this case and should prove to be slightly faster.
One way to check if all elements in a list are the same is to stuff them into a HashSet
and check the amount of items in the HashSet
afterwards: If you only have one item, then they are all equal...
精彩评论