Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

2 threads updating one object

Posted on 2007-12-05
14
Medium Priority
?
215 Views
Last Modified: 2013-12-16
i have 2 threads one updates a dataset so information on a primary gridview can be updated and viewed while other data loading occurs.
the 2nd thread updates the same dataset so that information on a secondary gridview is loaded. the problem is that the while loop in the threads skips out updating the dataset. will loop (like) 9 times with out actually updating the ds.

we are grabing information from a wcf service using paging fill.  and to get the bindings to controls to stay we have to pass it a temporary ds by ref and then merge that into the forms base dataset. everytime we loop we clear the pertinent datatable in the temporary ds to get ready for a new page of data. this seems to be the issue. sometimes the threads while loop will go back through and hit that before the merge actually occurs, thereby erasing the data that we need to proceed.

hopefully someone can help, and i know that this hasn't been explained the best so let me know what you need.
0
Comment
Question by:p_davis
  • 9
  • 5
14 Comments
 
LVL 40

Expert Comment

by:evilrix
ID: 20414427
0
 
LVL 40

Accepted Solution

by:
evilrix earned 2000 total points
ID: 20414548
The code below is a working example of how a mutex synchronizes threads. Without it the output is a mess. With it each thread outputs 10 lines and then defers to the other. To see the difference comment out the bits I've noted in the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
 
 
namespace cs_console
{
    class Program
    {
        static bool bQuit = false;
        static Mutex mtx = new Mutex(false);
 
        static void ThreadFunc()
        {
            while (!bQuit)
            {
                for (int x = 0; x < 10; ++x)
                {
                    //////////////////////////////////////////////////
                    // Comment out to see what it's like with no mutex
                    mtx.WaitOne();
                    //////////////////////////////////////////////////
                    for (int y = 0; y < 10; ++y)
                    {
                        Console.WriteLine("In thread: " + y.ToString());
                        Thread.Sleep(0);
                    }
                    //////////////////////////////////////////////////
                    // Comment out to see what it's like with no mutex
                    mtx.ReleaseMutex();
                    //////////////////////////////////////////////////
                }
            }
        }
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(Program.ThreadFunc));
            thread.Start();
 
            for (int x = 0; x < 10; ++x)
            {
                //////////////////////////////////////////////////
                // Comment out to see what it's like with no mutex
                mtx.WaitOne();
                //////////////////////////////////////////////////
                for (int y = 0; y < 10; ++y)
                {
                    Console.WriteLine("In main: " + y.ToString());
                    Thread.Sleep(0);
                }
                //////////////////////////////////////////////////
                // Comment out to see what it's like with no mutex
                mtx.ReleaseMutex();
                //////////////////////////////////////////////////
            }
 
            bQuit = true;
 
            thread.Join();
        }
    }
}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20414579
If you just want one thread to signal the other thread when to clear the ds, consider using an AutoResetEvent: -

http://msdn2.microsoft.com/en-us/library/system.threading.autoresetevent.aspx

0
NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

 
LVL 22

Author Comment

by:p_davis
ID: 20414740
thanks for the ideas i will try. i had been messing with locks and monitor but nothing seemed to work the way i thought it should.

should the mutex calls be wrapped in a try/finally block so the release always gets called?
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20414751
The following example uses 2 auto reset events to pass signals between main and thread. Comments in the code should clarify what is going on: -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
 
 
namespace cs_console
{
    class Program
    {
        static bool bQuit = false;
        static Mutex mtx = new Mutex(false);
        static AutoResetEvent autoEventThread = new AutoResetEvent(false);
        static AutoResetEvent autoEventMain = new AutoResetEvent(false);
 
        static void ThreadFunc()
        {
            while (!bQuit)
            {
                for (int x = 0; x < 10; ++x)
                {
                    //////////////////////////////////////////////////////
                    // Wait for main to signal
                    autoEventThread.WaitOne();
                    //////////////////////////////////////////////////////
 
                    if (!bQuit)
                    {
                        //////////////////////////////////////////////////
                        // Comment out to see what it's like with no mutex
                        mtx.WaitOne();
                        //////////////////////////////////////////////////
                        for (int y = 0; y < 10; ++y)
                        {
                            Console.WriteLine("In thread: " + y.ToString());
                            Thread.Sleep(0);
                        }
                        //////////////////////////////////////////////////
                        // Comment out to see what it's like with no mutex
                        mtx.ReleaseMutex();
                        //////////////////////////////////////////////////
                        // Signal main
                        autoEventMain.Set();
                        //////////////////////////////////////////////////
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(Program.ThreadFunc));
            thread.Start();
 
            for (int x = 0; x < 10; ++x)
            {
                //////////////////////////////////////////////////
                // Use event to ensure main runs before thread
                // and do two main loops to one thread loop
                if ((x > 0) && (x % 2) == 0)
                {
                    // Signal thread
                    autoEventThread.Set();
                    // Wait for thread to signal
                    autoEventMain.WaitOne();
                }
                //////////////////////////////////////////////////
                // Comment out to see what it's like with no mutex
                mtx.WaitOne();
                //////////////////////////////////////////////////
                for (int y = 0; y < 10; ++y)
                {
                    Console.WriteLine("In main: " + y.ToString());
                    Thread.Sleep(0);
                }
                //////////////////////////////////////////////////
                // Comment out to see what it's like with no mutex
                mtx.ReleaseMutex();
                //////////////////////////////////////////////////
            }
 
            bQuit = true;
 
            //////////////////////////////////////////////////////
            // Signal thread
            autoEventThread.Set();
            //////////////////////////////////////////////////////
 
            thread.Join();
        }
    }
}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20414761
>> should the mutex calls be wrapped in a try/finally block so the release always gets called?
You need to ensure your code is exception safe. I've left that out for clarity.
0
 
LVL 22

Author Comment

by:p_davis
ID: 20414843
ok, that seems to work better but it also seems creates a problem that i saw earlier

after loading the data i have to sort the primary grid so the data shows (otherwise it is just blank)
0
 
LVL 22

Author Comment

by:p_davis
ID: 20414852
meaning i have to manually click on the column header on the grid that is on the  ui.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20414867
>> ok, that seems to work better but it also seems creates a problem that i saw earlier
Creates or shows up existing?
0
 
LVL 22

Author Comment

by:p_davis
ID: 20414949
before the way i was doing it it would load after a certain amount of time but it would loop through with the clearing the datatable several times and then it would go through.
you could see the data actively being loaded into both gridviews but now you can't until you click on the column header

>>Creates or shows up existing?
i guess it could be debatable, but i'm hoping we won't as i would like to know how to correct this
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20414982
Using try/finally to ensure code is exception safe...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
 
 
namespace cs_console
{
    class Program
    {
        static bool bQuit = false;
        static Mutex mtx = new Mutex(false);
 
        static void ThreadFunc()
        {
            while (!bQuit)
            {
                for (int x = 0; x < 10; ++x)
                {
                    if (!bQuit)
                    {
                        try
                        {
                            //////////////////////////////////////////////////
                            // Comment out to see what it's like with no mutex
                            mtx.WaitOne();
                            //////////////////////////////////////////////////
                            for (int y = 0; y < 10; ++y)
                            {
                                Console.WriteLine("In thread: " + y.ToString());
                                Thread.Sleep(0);
                            }
                            //////////////////////////////////////////////////
                        }
                        finally
                        {
                            //////////////////////////////////////////////////
                            // Comment out to see what it's like with no mutex
                            mtx.ReleaseMutex();
                            //////////////////////////////////////////////////
                        }
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(Program.ThreadFunc));
            thread.Start();
 
            for (int x = 0; x < 10; ++x)
            {
                try
                {
                    //////////////////////////////////////////////////
                    // Comment out to see what it's like with no mutex
                    mtx.WaitOne();
                    //////////////////////////////////////////////////
                    for (int y = 0; y < 10; ++y)
                    {
                        Console.WriteLine("In main: " + y.ToString());
                        Thread.Sleep(0);
                    }
                    //////////////////////////////////////////////////
                }
                finally
                {
                    //////////////////////////////////////////////////
                    // Comment out to see what it's like with no mutex
                    mtx.ReleaseMutex();
                    //////////////////////////////////////////////////
                }
            }
 
            bQuit = true;
 
            thread.Join();
        }
    }
} 

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20415004
>> i guess it could be debatable, but i'm hoping we won't as i would like to know how to correct this
Well, I think it's fair to say it's probably an existing issue that has now manifested due to introduction of synchronization. I'm not sure I can help you out with that. I think you'll need to do a little debugging unfortunately.
0
 
LVL 22

Author Comment

by:p_davis
ID: 20415031
no matter, thank you for your posts.  the last part-- all i did was reset the bindings on the bindingsource and the data loaded fine.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20415100
>> all i did was reset the bindings on the bindingsource and the data loaded fine.
Great, I'm glad you figured that out. That kind of stuff -- not my strength :)
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
Suggested Courses

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question