Почему не делает многопоточности в C#, достигают 100% ЦП?

30
задан Brian Tompsett - 汤莱恩 31 August 2015 в 21:12
поделиться

13 ответов

У Вас есть значительная блокировка в рамках Вашего приложения? Если потоки ожидают друг друга много, который мог бы легко объяснить его.

Кроме того (и другие данные ответы), очень трудно предположить, действительно. Профилировщик является Вашим другом...

РЕДАКТИРОВАНИЕ: Хорошо, учитывая комментарии ниже, я думаю, что мы на что-то:

более дорогостоящая CPU часть моего кода является вызовом dll через COM (тот же внешний метод называют от всех потоков).

метод COM работает в STA случайно? Если так, это будет только использовать один поток, сериализируя вызовы. Я сильно подозреваю, что это - ключ к нему. Это подобно наличию блокировки вокруг того вызова метода (не совсем то же, по общему признанию).

25
ответ дан Jon Skeet 27 November 2019 в 23:43
поделиться

Проблемой является COM-объект. Это - STA, и у меня не может или быть двух экземпляров, работающих одновременно на том же процессе. Когда я создаю экземпляр для COM-класса, другой становится неприменимым.

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

Благодарит всех;)

0
ответ дан Victor Rodrigues 27 November 2019 в 23:43
поделиться

Еще одно примечание, Вы попытались запустить свой код не из Visual Studio (независимо от выпуска / параметры настройки отладки)?

0
ответ дан Tomas Pajonk 27 November 2019 в 23:43
поделиться

Возможно, я неправильно понимаю что-то, но Вы сказали, что ни один из Ваших запросов (каждый в отдельном потоке) не достигает 100% ЦП.

, Какую операционную систему Вы используете?

я, кажется, неопределенно вспоминаю, что в старых версиях окон (например, ранний XPS и 2000-е), загрузку ЦП рассмотрели от общего количества двух процессоров, таким образом, единственный поток не смог сделать его прошлыми 50%, если это не был неактивный процесс..

0
ответ дан Uri 27 November 2019 в 23:43
поделиться

Таким образом, Вы решили проблему использования единственного COM-объекта, и теперь имейте проблему IO.

увеличенное время выполнения для нескольких потоков, вероятно, из-за смешивания случайного IO вместе, который замедлит все это.

, Если набор данных впишется в RAM, попытайтесь видеть, можно ли выбрать его с упреждением в кэш. Возможно, просто считав данные, или возможно размещение в ОЗУ это вместе с командой для предоставления доступа к нему доступным.

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

0
ответ дан Zan Lynx 27 November 2019 в 23:43
поделиться

Это не ответ действительно, но Вы проверили perfmon для наблюдения, какие ресурсы он использует, и Вы выполнили профилировщиков на коде для наблюдения, где он проводит время?

, Как Вы решили, что IO или другой не ресурсы ЦП не являются узким местом?

можно ли дать краткое описание того, что делают потоки?

0
ответ дан Tim 27 November 2019 в 23:43
поделиться

если Ваш процесс работает на CPU 0 и родительских потоках там, максимум, которого это будет когда-либо достигать, составляет 50%. Посмотрите, есть ли у Вас потоки, работающие на обоих ядрах или всего на один. Я рисковал бы предположить, что Вы изолируетесь к одноядерному, или что один из Ваших зависимых ресурсов заблокирован на одноядерном. Если это поразит точно 50% тогда, то одноядерным, очень вероятно, будет Ваше узкое место.

0
ответ дан Chris Ballance 27 November 2019 в 23:43
поделиться

Это кажется, что производительность Вашего приложения не может быть 'связана' суммой доступных ресурсов CPU. При обработке запросов по сети CPU может ожидать данных для прибытия, или сетевого устройства для передачи данных. С другой стороны, если необходимо искать данные для обрабатывания запроса, CPU может ожидать диска.

0
ответ дан Dana the Sane 27 November 2019 в 23:43
поделиться

Это зависит, что Ваша программа делает - работа, выполненная Вашими параллельными Запросами, могла быть IO-bound - ограниченный скоростью (например), Вашим жестким диском - а не зависящий от ЦП, когда Вы будете видеть, что Ваш ЦП поражает 100%.

После редактирования, это действительно кажется, что объекты STA COM могли бы быть преступником.

Делают все потоки называют тот же экземпляр COM-объекта? Было бы возможно сделать Ваши потоки STA рабочего потока и создать отдельный экземпляр COM-объекта на каждом потоке. Таким образом могло бы быть возможно избежать узкого места STA.

, Чтобы сказать, является ли COM coclass STA:

class Test
{
  static void Main() //This will be an MTA thread by default
  {
    var o = new COMObjectClass();
    // Did a new thread pop into existence when that line was executed?
    // If so, .NET created an STA thread for it to live in.
  }
}
4
ответ дан mackenir 27 November 2019 в 23:43
поделиться

Это не, вероятно, больше процессор, который является узким местом для завершения Вашего процесса. Узкое место, вероятно, переместилось в доступ к диску, доступ к сети или доступ к памяти. У Вас могла также быть ситуация, где Ваши потоки конкурируют за блокировки.

Только Вы знаете точно, что делают Ваши потоки, таким образом, необходимо посмотреть на них с вышеупомянутым в памяти.

13
ответ дан Rob Prouse 27 November 2019 в 23:43
поделиться

Проблемой является COM-объект.

Большинство COM-объектов, выполненных в контексте 'однопоточной квартиры'. (Вы, возможно, видели аннотацию [STAThread] на основной метод приложения.NET время от времени?)

Эффективно это означает, что все отправки к тому объекту обрабатываются единственным потоком. Бросок большего количества ядер в проблеме просто дает Вам больше ресурсов, которые могут сидеть без дела и ожидать или сделать другие вещи в.NET.

Вы могли бы хотеть смотреть на эту статью от Joe Duffy (главный параллельный парень.NET в Microsoft) по теме.

http://www.bluebytesoftware.com/blog/PermaLink,guid,8c2fed10-75b2-416b-aabc-c18ce8fe2ed4.aspx

На практике, если необходимо сделать набор вещей против единственного COM-объекта как это, Вы политы из шланга, потому что.NET просто сериализирует схемы доступа внутренне за Вашей спиной. Если можно создать несколько COM-объектов и использовать их тогда, можно решить вопрос, потому что каждый может быть создан и получен доступ от отличного потока STA. Это будет работать, пока Вы не поразите приблизительно 100 потоков STA, тогда дела будут идти wonky. Для получения дополнительной информации см. статью.

17
ответ дан Edward KMETT 27 November 2019 в 23:43
поделиться

Вы уверены, что Ваши задачи требуют интенсивного действия процессора? Там какой-либо IO обрабатывает? Это может быть причиной Вашей 50%-й загрузки.

Тест: Попытайтесь использовать только 2 потока и установите его привязка каждого потока для каждого Ядра. Тогда откройте диспетчер задач и часы загрузка обоих ядер.

0
ответ дан bruno conde 27 November 2019 в 23:43
поделиться

I think I had a similar problem. I was creating multiple threads in c# that ran c++ code through a COM interface. My dual core CPU never reached 100%.

After reading this post, I almost gave up. Then I tried calling SetApartmentState(ApartmentState.STA) on my Threads.

After only changing this, the CPU maxed out.

2
ответ дан 27 November 2019 в 23:43
поделиться
Другие вопросы по тегам:

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