【问题标题】:Synchronisation of Two Threads两个线程的同步
【发布时间】:2009-05-12 13:23:51
【问题描述】:

我在c#中有两个线程。现在我需要等待一个特定的语句被执行,然后我才能在另一个线程中继续执行,这显然是一种同步的情况。 是否有任何代码可以像使用内置方法一样执行此操作?

这是代码示例:

    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);
            }

    }

这会从代码选择的所需主机接收数据:

    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);

    }

因此,为了开始接收数据,我需要将套接字初始化为特定的远程主机,这在我单击列表框中显示的主机之一时完成。 为此,我需要同步。

【问题讨论】:

  • 抱歉,我错过了这个问题。

标签: c# multithreading synchronization


【解决方案1】:

看看AutoResetEventManualResetEvent。它们是使线程之间的同步成为可能的信号。

需要等待某事完成的第一个线程将执行 myEvent.WaitOne(),它会阻塞直到另一个线程调用 myEvent.Set()。

假设我们有两个线程,其中一个线程需要在另一个线程继续之前进行某种初始化。然后在两者之间共享一个 AutoResetEvent,我们称之为 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");
    }
}

不要将此与访问顺序无关紧要的共享资源混淆。例如,如果您有一个共享列表或共享字典,则需要将其包装在互斥体中以保证它们正确执行。

// 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;
    }
}

【讨论】:

  • +1 用于回答所提出的问题,而不是您想象的问题。 . .就像我所做的一样。 . .
  • ok.. 因此,使用相同格式的代码,如果我的方法 startAccept() 必须等待事件 listBox1_Click(Object Sender, EventArgs e) 被执行,代码会是什么样子? . 我不知何故无法理解 myEvent 对应的内容。
  • @Awik:如果您编辑上面的问题以包含一些具体的代码示例,那么给您更准确的答案会更容易。
【解决方案2】:

您可以使用 AutoResetEvent。

在以下示例中,两个方法被不同的线程调用,DoSomethingA() 将在 DoSomethingB() 开始之前执行并完成:

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();
}

注意:记得处理 AutoResetEvent :)

【讨论】:

    【解决方案3】:

    Java 有一个叫做 Join 的东西。我怀疑 C# 中也会有预定义的方法。

    【讨论】:

    • join 等待线程终止,而不是特定语句
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多