Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Синхронизация потоков

1.8K
30 марта 2011 года
NextTime
217 / / 19.12.2007
Здравствуйте. Программа на C#.Net.
Есть функция func1, которая долго выполняет определённую задачу (более 30 секунд).
Необходимо вызвать её с различными параметрами в различных потоках и вывести результат её работы. Количество потоков = количеству процессоров (ядер) в системе.

Реализовал я эту задачу так. Создал func2, которая запускает func1 с различными параметрами и контроллирует количество одновременно выполняемых потоков (AutoResetWaitHandle). Также создал func3, которая ожидает результаты в Queue, используя AutoResetWaitHandle.

Если func1 долго выполняется, то всё хорошо, но, если она выполняется моментально, то количество выданных AutoResetWaitHandle.Set() не совпадает с количеством результатов в Queue, словно некоторые Set() недовызываются, но это не так. Проверял всё. Количество вызванных Set и WaitOne совпадает. Почитал, вроде, разрешено вызывать Set раньше, чем WaitOne, но, такое ощущение, что нет, что остальные Set игнорируются.
Помогите, пожалуйста, исправить ошибку и оптимизировать код. Чтобы программа была действительно потокобезопасной и не появлялось недочётов.
Программист я, можно сказать, начинающий, поэтому прошу подробнее объяснить.
Прикрепляю к сообщению проект VS2010: [ATTACH]5010[/ATTACH]
Заранее спасибо.
5
02 апреля 2011 года
hardcase
4.5K / / 09.08.2005
AutoResetWaitHandle тебе не подходит, для организации счетчика нужно использовать семафор.
Либо его аналог в духе:
Код:
using System;
using System.Linq;

class Program
{
  static void Job(int index)
  {
    Console.WriteLine("Job {0} started", index);
    System.Threading.Thread.Sleep(new Random().Next(10000));
    Console.WriteLine("Job {0} completed", index);
  }

  static void StartJobsAndWait(int count)
  {
    if(count <= 0)
      throw new ArgumentOutOfRangeException("count");

    var jobs = Enumerable.Range(0, count)
      .Select(index =>
      {
        var job = new Action<int>(Job);
        return new
        {
          Job = job,
          AsyncResult = job.BeginInvoke(index, null, null)
        };
      })
      .ToList();

    foreach(var jobInfo in jobs)
      jobInfo.Job.EndInvoke(jobInfo.AsyncResult);
  }

  public static void Main(string[] args)
  {
    StartJobsAndWait(10);
    Console.Write("Press any key to continue . . . ");
    Console.ReadKey(true);
  }
}



А вообще, я бы использовал TPL библиотеку из .NET4.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог