Основной вопрос Threading - PullRequest
       1

Основной вопрос Threading

0 голосов
/ 03 сентября 2010

Этот вопрос, вероятно, задавался различными способами ранее, но вот что я хочу сделать. Я собираюсь иметь форму Windows со многими вкладками. Каждая вкладка будет содержать объект сетки. Для каждой вкладки / сетки, созданной пользователем, я бы хотел порождать выделенный поток, чтобы заполнить содержимое этой сетки постоянно поступающей информацией. Кто-нибудь может привести пример, как это сделать безопасно?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 03 сентября 2010

Внутри инициализации для вкладки (при условии WinForms, пока я не увижу иначе):

Thread newThread = new Thread(() =>
{
    // Get your data

    dataGridView1.Invoke(new Action(() => { /* add data to the grid here */ } );
});

newThread.Start();

Это, очевидно, самый простой пример. Вы также можете порождать потоки, используя ThreadPool (что чаще всего делается в серверных приложениях).

Если вы используете .NET 4.0, у вас также есть библиотека Task Parallel, которая также может помочь.

1 голос
/ 03 сентября 2010

Есть два основных подхода, которые вы можете использовать.Выберите тот, который имеет наибольшее значение в вашей ситуации.Часто нет правильного или неправильного выбора.Они оба могут работать одинаково хорошо во многих ситуациях.У каждого есть свои преимущества и недостатки.Как ни странно, сообщество, кажется, слишком часто упускает из виду этот метод.Я не уверен, почему это действительно так.Недавно я наткнулся на этот вопрос, в котором все рекомендовали подход «толкать», несмотря на то, что это идеальная ситуация для метода «тянуть» (была одна бедная душа, которая пошла против стада и была отвергнута и в конце концов удалила свой ответ, оставивтолько я как одинокий диссидент).

Метод Push

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

void WorkerThread()
{
  while (true)
  {
    object data = GetNewData();
    yourForm.Invoke(
      (Action)(() =>
      {
        // Add data to your grid here.
      }));
  }
}

Метод извлечения

Сделайте так, чтобы поток пользовательского интерфейса извлекал данные из рабочего потока.Рабочий поток будет помещать новые элементы данных в общую очередь, а поток пользовательского интерфейса будет периодически удалять эти элементы.Преимущество здесь в том, что вы можете регулировать объем работы, которую каждый поток выполняет независимо.Очередь - это ваш буфер, который будет уменьшаться и увеличиваться по мере уменьшения и увеличения загрузки процессора.Он также отделяет логику рабочего потока от потока пользовательского интерфейса.Недостатком является то, что если ваш поток пользовательского интерфейса не опрашивает достаточно быстро или поддерживать рабочий поток может переполнить очередь.И, конечно же, элементы данных не будут отображаться в реальном времени в вашей сетке.Однако, если вы установите интервал System.Windows.Forms.Timer достаточно коротким, это не будет проблемой для вас.

private Queue<object> m_Data = new Queue<object>();

private void YourTimer_Tick(object sender, EventArgs args)
{
  lock (m_Data)
  {
    while (m_Data.Count > 0)
    {
      object data = m_Data.Dequeue();
      // Add data to your grid here.
    }
  }
}

void WorkerThread()
{
  while (true)
  {
    object data = GetNewData();
    lock (m_Data)
    {
      m_Data.Enqueue(data);
    }
  }
}
0 голосов
/ 03 сентября 2010

У вас должен быть массив потоков, чтобы можно было их контролировать

List<Thread> tabs = new List<Thread>();

...

Чтобы добавить новый, было бы как:

tabs.Add( new Thread( new ThreadStart( TabRefreshHandler ) );
//Now starting:
tabs[tabs.Count - 1].Start();

И, наконец, в TabRefreshHandler вы должны проверить, какой номер вызывающего потока, и вы будете знать, какую вкладку нужно обновить!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...