Click here to Skip to main content
15,897,371 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have two thread ,Each running two threads, no error appear. but run together,the backgroundWorker2 tip :can't clone null.....(I check variable J value is greater than 100),in this case,how to lock global variable?

C#
Bitmap img; //global variable

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int i = 0;

            do
            {
             
                    img = (Bitmap)Image.FromFile(@"i:\1.jpg");
                    img.Dispose();
             
                i++;
                backgroundWorker3.ReportProgress(i,"");
                Thread.Sleep(10);
            } while (!backgroundWorker4.CancellationPending);
        } 

 private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            int j= 0;
            do
            {
                //img = (Bitmap)Image.FromFile(@"i:\1.jpg");
               
                if (img != null)
                {
                    lock (img)
                    {
                        Bitmap tempImg = (Bitmap)img.Clone();
                    }
                }
           
               
                j++;
                backgroundWorker4.ReportProgress(j, "");
                Thread.Sleep(10);
            } while (!backgroundWorker4.CancellationPending);
        }
Posted

1 solution

You are locking in the second thread (or the 4th one, I can't tell). Just repeat the process in the other one, however its not the best way of doing it (possible race condition)

First, you should mark your variable as volatile[^], which tells the compiler that the object may be referenced from multiple threads. You really only need to do this if accessing from multiple threads at the same time (one counting blue pixels, one counting red, one writing orange ones, etc).

A better object to use other than the lock is to use an AutoResetEvent[^]. This can signal one thread to another that its done using the object. Otherwise you are playing with a race condition, where one thread gets to the resource before the other one has initialized it or you aren't sure which one gets there first.

You need to ensure that the second thread only uses the resource after its been set up by the other thread. The link above has an example on how to use the AutoResetEvent, you just watch for it in the second thread and the first thread signals that the resource is ready for the other thread.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 12-Sep-13 22:37pm    
5ed.

I would only add: there is no such thing as "global variable", in .NET (finally!). In respect to the matter under discussion, the only important things is that a variable or a type's member (static or instance one) is shared between threads.

—SA
Ron Beyer 12-Sep-13 22:41pm    
Thanks, good points, and often a stumbling place for people coming from other languages like C++ or VB (6 or less) is the inability to understand that everything has a lifetime and a scope.
Sergey Alexandrovich Kryukov 12-Sep-13 22:47pm    
Even a global variable... :-)
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900