C # - Как мне разбудить спящую нить? - PullRequest
3 голосов
/ 14 апреля 2011

Я смог решить это сам, прочитав немного дальше, я предполагал, что вы должны ссылаться на потоки, а не на объекты. Это работает сейчас. :)

Оригинальный пост:


Я посмотрел на большинство подобных вопросов, и я видел много ответов, содержащих мониторы, импульсы и т. Д., Но я не могу заставить его работать.

Я довольно новичок в C #, так что, если я неправильно использую потоки, пожалуйста, прости меня Но моя проблема заключается в следующем:

У меня есть 4 потока, один из которых уменьшает целое число в столбце в трех разных таблицах на одну. Затем 3 различных потока, которые выполняют действие в зависимости от того, достигло ли какое-либо из значений ноль.

Что я хочу сделать, так это чтобы нить, считающая обратный отсчет, только пробуждала правильную нить трех других, если что-то достигает нуля. Чтобы проверить это не проблема, проблема состоит в том, чтобы разбудить потоки. В настоящее время у меня есть рабочий, в котором все они запускаются одновременно, но я хочу использовать это для повышения эффективности.

Вот код, который я использую, я включил только один для простоты, и это та же идея. Это как я должен это использовать?

Это то, что я получил, прочитав примеры и результаты в Google.

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 секунд. Было бы здорово, чтобы он мог работать каждую секунду.

1 Ответ

0 голосов
/ 22 мая 2011

Самый простой способ сделать это - иметь три отдельных объекта блокировки, каждый рабочий поток будет ожидать определенной блокировки, а управляющий поток будет устанавливать правильную блокировку на основе уменьшенных значений.1002 *

Каждый работник работает примерно так:

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