views:

289

answers:

3
+2  Q: 

Synchronisation c#

I have two threads in c#.. Now i need to wait for a particular statement to be executed before I can continue execution in the other thread which obviously is a case of synchronisation. Is there any code that can carry this out as in using an in-built method?

OK guys.. This is the code example:

    public void StartAccept()
    {


            try
            {
                newSock.BeginAccept(new AsyncCallback(Accepted), newSock);
            }
            catch (ArgumentException)
            {
                MessageBox.Show("Error in arguments while using begin-accept", "Error", MessageBoxButtons.OK);
            }
            catch (ObjectDisposedException)
            {
                MessageBox.Show("socket closed while using begin-accept", "Error", MessageBoxButtons.OK);
            }
            catch (SocketException)
            {
                MessageBox.Show("Error accessing socket while using begin-accept", "Error", MessageBoxButtons.OK);
            }
            catch (InvalidOperationException)
            {
                MessageBox.Show("Invalid operation while using begin-accept", "Error", MessageBoxButtons.OK);
            }
            catch (Exception)
            {
                MessageBox.Show("Exception occurred while using begin-accept", "Error", MessageBoxButtons.OK);
            }

    }

This receives data from the desired host which is selected by the code:

    private void listBox1_Click(object sender, EventArgs e)
    {



        String data = (String)this.listBox1.SelectedItem;

        ip = Dns.GetHostAddresses(data);

        clientIP = new IPEndPoint(ip[0], 5555);

        newSock.Bind(clientIP);
        newSock.Listen(100);

    }

So in order to start receiving data I need to initialise the socket to the particular remote host which is done when i click on one of the hosts shown in the listbox. For this I need the synchronization.

Hope this helps.

A: 

Java has something called Join. I suspect there will be a predefined method in C# too.

Geek
join waits until a thread terminates, not a particular statement
DonkeyMaster
+10  A: 

Take a look at AutoResetEvent and ManualResetEvent. They are signals that makes synchronisation between threads possible.

The first thread that needs to wait for something to get done will do myEvent.WaitOne(), which blocks until the other thread calls myEvent.Set().

Let's say we have two threads, where one of them needs to do some kind of initialisation before the other thread can continue. You then share a AutoResetEvent between the two, let's call it myEvent.

// Signal example

using System;
using System.Threading;

class MySync
{
    private readonly AutoResetEvent _myEvent;
    public MySync(AutoResetEvent myEvent)
    {
        _myEvent = myEvent;
    }

    public void ThreadMain(object state)
    {
        Console.WriteLine("Starting thread MySync");
        _myEvent.WaitOne();
        Console.WriteLine("Finishing thread MySync");
    }
}

class Program
{
    static void Main(string[] args)
    {
        AutoResetEvent myEvent = new AutoResetEvent(false);
        MySync mySync = new MySync(myEvent);
        ThreadPool.QueueUserWorkItem(mySync.ThreadMain);
        Console.WriteLine("Press enter to continue...");
        Console.ReadLine();
        myEvent.Set();
        Console.WriteLine("Press enter to continue...");
        Console.ReadLine();
        Console.WriteLine("Finishing");
    }
}

Don't confuse this with a shared resource where the access order doesn't matter. For example, if you have a shared list or a shared dictionary you need to wrap it in a mutex in order to guarantee that they execute correctly.

// Mutex example

object mySync = new object();
Dictionary<int, int> myDict = new Dictionary<int, int>();

void threadMainA()
{
    lock(mySync)
    {
        mySync[foo] = bar;
    }
}

void threadMainB()
{
    lock(mySync)
    {
        mySync[bar] = foo;
    }
}
Mats Fredriksson
+1 for anwswering the question that was asked, not one you imagined . . . like what I did . . .
Binary Worrier
ok.. So with the same format of the code, if my method startAccept() must wait for the event listBox1_Click(Object Sender, EventArgs e) to be executed what would the code look like?.. I am somehow not being able to understand what myEvent would correspond to.
Avik
@Awik: If you edit your question above to include some concrete code examples it would be easier to give you a more precis answer.
Mats Fredriksson
+2  A: 

You can use an AutoResetEvent.

In the following example two methods get called by different threads and DoSomethingA() will be executed and finish before DoSomethingB() starts:

AutoResetEvent resetEvent = new AutoResetEvent(false);

void ThreadWorkerA()
{
    // perform some work
    DoSomethingA();

    // signal the other thread
    resetEvent.Set();
}

void ThreadWorkerB()
{
    // wait for the signal
    resetEvent.WaitOne();

    // perform the new work
    DoSomethingB();
}

Note: remember to dispose the AutoResetEvent :)

Maghis