【问题标题】:C# - How do I Wake a Sleeping thread?C# - 如何唤醒休眠线程?
【发布时间】:2011-08-05 05:09:07
【问题描述】:

通过进一步阅读,我自己能够解决这个问题,我假设您应该引用线程而不是对象。现在可以了。 :)

原帖:


我已经研究了大多数类似的问题,并且我已经看到了很多包含监视器、脉冲等的答案,但是我无法让它发挥作用。

我对 C# 比较陌生,所以如果我使用错误的线程,请原谅我。但我的问题如下;

我有 4 个线程,其中一个将三个不同表中的列中的整数减一。然后 3 个不同的线程根据任何值是否达到零来执行操作。

我想要做的是让线程倒计时只有在某些东西达到零时才唤醒其他三个的正确线程。检查这不是问题,问题是唤醒线程。我目前确实有一个可以同时运行的工作,但我想使用它来提高效率。

这是我使用的代码,为了简单起见,我只包含了一个,并且是相同的想法。我应该这样使用吗?

这是我从谷歌上阅读示例和结果得到的。

public class UpdateQueueSuggestion

{

public void startGame()
{      
    Thread Check = new Thread(new ThreadStart(checkUpdate));
    Check.Start();
}

public void checkUpdate()
{
    // (...) Some intialization of variables

    // Create the thread used for when entries in the Queue table reaches 0.
    Thread Build = new Thread(new ThreadStart(performBuildingUpdate));
    Build.Start();

    // Some sqlcommands.

    while (true)
    {
        try
        {
            // Enter to synchronize, if not it yields
            // Object synchronization method was called from an unsynchronized block of code.
            Monitor.Enter(this);
            connection.Open();

            // Execute commands. Get COUNT(*) for results reaching 0 in tables and save int in i.

            if (i > 0)
            {
            // Pulse the thread called Build, in order to wake it again.
                Monitor.Pulse(Build);
            }
        }

        finally
        {
            // Exit monitor.
            Monitor.Exit(this);
            connection.Close();
        }
        // This one is supposed to run each second, decrement and check for zeros.
        // Works just fine if I just put everything in here without monitors,
        // but as I said I want to split it up for efficiency.
        Thread.Sleep(1000);
    }

}

public void performBuildingUpdate()
{
    // Some sqlcommands

    while (true)
    {
        Monitor.Enter(this);
        try
        {
            connection.Open();
            // Execute commands.
        }

        finally
        {
            connection.Close();
            Monitor.Wait(this);
            Monitor.Exit(this);
        }
    }

}

}

非常感谢任何帮助,谢谢。

如果有人想知道,那是我们正在为学校的 C# 课程制作的浏览器游戏项目。这应该花费游戏事件的大致时间。目前,我们在一个线程中运行所有命令,并且每 10 秒运行一次。让它能够每秒运行会很棒。

【问题讨论】:

  • 建议您阅读此优秀资源:albahari.com/threading
  • 请不要在标题前加上 Solved 而是标记答案(甚至在需要时添加)

标签: c# asp.net multithreading mutex monitor


【解决方案1】:

最直接的方法是拥有三个独立的锁对象,每个工作线程将等待一个特定的锁,控制线程将根据递减的值脉冲正确的锁。

public class Controller
{
    private object _lock1;
    private object _lock2;
    private object _lock3;

    private Thread _worker1;
    private Thread _worker2;
    private Thread _worker3;


    public Controller()
    {
        _lock1 = new object();
        _lock2 = new object();
        _lock3 = new object();

        _worker1 = new Thread(ExecuteWorker, _lock1);
        _worker2 = new Thread(ExecuteWorker, _lock2);
        _worker3 = new Thread(ExecuteWorker, _lock3);

        lock (_lock1)
        {
            _worker1.Start();
            Monitor.Wait(_lock1);
        }
        lock (_lock2)
        {
            _worker2.Start();
            Monitor.Wait(_lock2);
        }
        lock (_lock3)
        {
            _worker3.Start();
            Monitor.Wait(_lock3);
        }
    }

    public void Execute()
    {
        // Perform database logic, assuming decremented values are stored.
        int value1 = DecrementValueFromDB();
        int value2 = DecrementValueFromDB();
        int value3 = DecrementValueFromDB();

        if (value1 == 0)
        {
            lock (_lock1)
            {
                Monitor.Pulse(_lock1);
            }
        }

        if (value2 == 0)
        {
            lock (_lock2)
            {
                Monitor.Pulse(_lock2);
            }
        }

        /// ... repeat for third value
        //
    }
}

每个工人都在运行类似的东西:

static void ExecuteWorker(object lockObject)
{
    lock (lockObject)
    {
        // Signal to thread creator that the thread is running.
        Montior.Pulse(lockObject);

        // Keep running while we have not been marked to shut down
        while (!complete)
        {
            Monitor.Wait(lockObject);
            // logic to execute when signaled (value == 0)
        }
    }
}

【讨论】:

    猜你喜欢
    • 2014-07-15
    • 2020-05-21
    • 2011-06-01
    • 2012-08-15
    • 1970-01-01
    • 2014-07-29
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多