Очереди потока для макетов

попробуйте этот код:

CultureInfo french = CultureInfo.GetCultureInfo("fr-FR");
CultureInfo arabic = CultureInfo.GetCultureInfo("ar-AR");
String nowStr = DateTime.Now.ToString(french);
string dt = DateTime.Parse(nowStr, french).ToString(arabic);
Console.WriteLine(" DATE : " + nowStr.ToString());
Console.WriteLine(" DATE : " + dt.ToString());
Console.Read();
6
задан Casey Gay 28 April 2009 в 00:56
поделиться

7 ответов

Даже если другие ответы хороши если вам нужен другой вариант (у вас никогда не будет достаточно вариантов), то как об этом в качестве идеи.

Просто поместите данные для каждого задания в структуру, которая находится в стеке FIFO.

Создайте 15 потоков.

Каждый поток получит следующее задание из стека, отбрасывая его.

Когда поток завершает обработку, получает следующее задание, если стек пуст, поток умирает или просто спит, ожидая.

Единственная сложность, которую довольно просто решить,всплывающее окно находится в критическом разделе (синхронизировать чтение / всплывающее окно).

3
ответ дан 16 December 2019 в 21:46
поделиться

Re: «как-то дождаться их завершения»

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

Другой вариант - вручную создать потоки и создать поток foreach, thread.Join ()

Вы можете использовать это (я использую это во время тестирования)

     private void Repeat(int times, int asyncThreads, Action action, Action done) {
        if (asyncThreads > 0) {

            var threads = new List<Thread>();

            for (int i = 0; i < asyncThreads; i++) {

                int iterations = times / asyncThreads; 
                if (i == 0) {
                    iterations += times % asyncThreads;                    
                }

                Thread thread = new Thread(new ThreadStart(() => Repeat(iterations, 0, action, null)));
                thread.Start();
                threads.Add(thread);
            }

            foreach (var thread in threads) {
                thread.Join();
            }

        } else {
            for (int i = 0; i < times; i++) {
                action();
            }
        }
        if (done != null) {
            done();
        }
    }

Использование:

// Do something 100 times in 15 background threads, wait for them all to finish.
Repeat(100, 15, DoSomething, null)
2
ответ дан 16 December 2019 в 21:46
поделиться

Когда вы ставите рабочий элемент в очередь потока, вы должны получить ручку ожидания обратно. Поместите их все в массив, и вы можете передать его в качестве аргумента функции WaitAll () .

1
ответ дан 16 December 2019 в 21:46
поделиться

Я бы просто использовал Task Parallel Library.

Вы можете сделать это как один простой цикл Parallel.For с вашими задачами, и он автоматически справится с этим довольно чисто. Если вы не можете дождаться C # 4 и реализации Microsoft, временный обходной путь - просто скомпилировать и использовать Mono-реализацию TPL . (Я лично предпочитаю реализацию MS, особенно более новые бета-версии, но Mono-версия является функциональной и распространяемой сегодня.)

1
ответ дан 16 December 2019 в 21:46
поделиться

Я бы использовал ThreadPool.

Перед тем, как начать работу, создайте ManualResetEvent и счетчик int. Добавьте каждое задание в ThreadPool, увеличивая счетчик каждый раз.

В конце каждого задания уменьшайте счетчик и, когда он достигает нуля, вызовите Set () для события.

В ваш главный поток, вызовите WaitOne () , чтобы дождаться завершения всех заданий.

1
ответ дан 16 December 2019 в 21:46
поделиться

ThreadPool может быть подходящим вариантом. Метод SetMaxThreads сможет ограничить количество выполняемых потоков. Однако это ограничивает максимальное количество потоков для процесса / домена приложений. Я бы не советовал использовать SetMaxThreads , если процесс запущен как служба.

private static ManualResetEvent manual = new ManualResetEvent(false);
private static int count = 0;

public void RunJobs( List<JobState> states )
{
     ThreadPool.SetMaxThreads( 15, 15 );

     foreach( var state in states )
     {
          Interlocked.Increment( count );
          ThreadPool.QueueUserWorkItem( Job, state );
     }

    manual.WaitOne();
}

private static void Job( object state )
{
    // run job
    Interlocked.Decrement( count );
    if( Interlocked.Read( count ) == 0 ) manual.Set();
}
0
ответ дан 16 December 2019 в 21:46
поделиться

Вот псевдокод того, как я бы подошел (это не использует ThreadPool, так что кто-то может получим лучший ответ:)

main
{
    create queue of 100 jobs
    create new array of 15 threads
    start threads, passing each the job queue
    do whatever until threads are done
}

thread(queue)
{
    while(queue isn't empty)
    {
        lock(queue) { if queue still isn't empty dequeue a thing }
        process the thing
    }

    queue is empty so exit thread
}

РЕДАКТИРОВАТЬ: Если ваша проблема заключается в том, как определить, когда потоки завершены, и вы используете обычные потоки C # (не потоки ThreadPooled), вы можете вызывать Thread.Join () для каждого потока с помощью необязательный таймаут, и он вернется только после завершения потока. Если вы хотите следить за тем, сколько потоков сделано, не зацикливаясь на одном, вы можете циклически просматривать их следующим образом:

for(int i = 0; allThreads.Count > 0; i++)
{
    var thisThread = allThreads[i % threads.Count];
    if(thisThread.Join(timeout)) // something low, maybe 100 ms or something
        allThreads.Remove(thisThread);
}
0
ответ дан 16 December 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: