Проблема с потоками

0 голосов
спросил 19 Дек, 07 от Daddyz (340 баллов) в категории Программные продукты Esri
Имею следующую проблему...
Для работающей программы моделирования было решено использовать отдельный поток с помощью BackgroundWorker'а, чтобы пользователь мог запустив моделирование, продолжить работу с ArcMap'ом не ощущая "тормозов" и "подвисания".
Однако использовав BackgroundWorker я существенно потерял в скорости моделирования (вместо 7-10 мин оно занимает около 2 часов). Как мне кажется, проблема стоит в приоритете потоков в Windows. Итак, мой вопрос как правильно использовать BackgroundWorker и как регулировать приоритет потока?
Искренне надеюсь на помощь сведущих людей...

25 Ответы

0 голосов
ответил 30 Янв, 08 от dindzilin (4,160 баллов)
Блин, я фигею... Прям как в сказке: а из одной шкуры сошьёшь мне 10 шапок? Ты еще 10 BackgroundWorkerов запусти, и удивляйся, почему чем их больше запускаешь, тем медленнее они работают. Ресурсы компа не ризиновые однако, освобождая память и проц для одного процесса, другим приходится довольствоваться малым. Ты попробуй сравнить скорость своей работы когда переливаешь воду из одной бочки в другую с помощью ведра и стакана? А я поудивляюсь, че этт ты так медленно стаканом работаешь?
    
    
0 голосов
ответил 30 Янв, 08 от Alexander1 (32,520 баллов)
Мultithreading и ArcObjects - это не просто использование BackgroundWorker'а.

Почитайте "Writing multithreaded ArcObjects code":

http://edndoc.esri.com/arcobjects/9.2/NET/2c2d2655-a208-4902-bf4d-b37a1de120de.htm
0 голосов
ответил 26 Фев, 10 от -3A- (5,220 баллов)
позволю себе поднять старую тему

столкнулся с такой же проблемой
закачка данных из дополнительного потока жутко тормозит

при этом все соединения создаются именно в рабочем потоке, в него передается только xml-строка со свойствами подключения к SDE (как рекомендовано в статье Writing multithreaded ArcObjects code)

никакие объекты ArcObjects, кроме созданных в потоке, больше не используются
то есть cross-threaded вызовов у меня нет

тот же код из основного потока работает на порядок быстрее

как заставить и так очень неторопливый ArcGIS Desktop нормально работать с потоками?
0 голосов
ответил 05 Апр, 10 от TDenis (42,620 баллов)
-3A-,
Не решили проблему?
Этот дополнительный поток - STA?
0 голосов
ответил 06 Апр, 10 от -3A- (5,220 баллов)
TDenis
нет, не решил image
поток - STA
0 голосов
ответил 06 Апр, 10 от TDenis (42,620 баллов)
Не выложите какой-нибудь упрощённый вариант, поглядеть?
0 голосов
ответил 06 Апр, 10 от pooperec (10,820 баллов)
Да, было бы интересно.

Хотел организовать подключение к серверам (SOM/SDE) в отдельных потоках. В итоге результат не впечатлил, так как все попытки передать созданные COM объекты через прокси, к успеху не привели. Вернее загрузка производилась, но стабильность работы оставляла желать лучшего (то один, то второй FeatureWorkspace при последующем обращении вылетали с ошибками, тоже происходило с SOM подключением).  Ещё откуда-то, в случайных местах появлялись deadlock'и, (полное зависание системы).

Возможно я ещё не дорос до создания многопоточных приложений. =)

З.Ы. Вопрос не по теме, если кто-то делал приложение с программным подключением к SDE и загрузкой слоя. У кого сколько времени занимает организация подключения (подключение + загрузка слоя с допустим 100 объектами) - у меня это занимает 1,7 секунд - хотелось бы ускорить/запаралелить...


0 голосов
ответил 06 Апр, 10 от -3A- (5,220 баллов)
вот как-то так:


void LoadDataAsync(object connection)
{
  IXMLSerializer serializer = new XMLSerializerClass();
  IPropertySet ps = (IPropertySet)serializer.LoadFromString((string)connection, null, null);

  IWorkspaceFactory2 wsf = null;
  switch ((esriWorkspaceType)ps.GetProperty("WORKSPACE_TYPE"))
  {
    case esriWorkspaceType.esriFileSystemWorkspace:
      wsf = new FileGDBWorkspaceFactoryClass();
      break;
    case esriWorkspaceType.esriLocalDatabaseWorkspace:
      wsf = new AccessWorkspaceFactoryClass();
      break;
    default:
       wsf = new SdeWorkspaceFactoryClass();
        break;
  }

  LoadData((IFeatureWorkspace)wsf.Open(ps, 0));
}

void LoadData(IFeatureWorkspace fws)
{
  ITable table = fws.OpenTable(TableName);

  ICursor cursor = table.Search(null, true);
  for (IRow row = cursor.NextRow(); row != null; row = cursor.NextRow())
  {
    // здесь читаем данные
  }
 
  Marshal.ReleaseComObject(cursor);
}

void Initialize(IWorkspace workspace)
{
  if (settings.AsyncDataLoad)
  {
    IPropertySet ps = workspace.ConnectionProperties;
    ps.SetProperty("WORKSPACE_TYPE", workspace.Type);

    IXMLSerializer serializer = new XMLSerializerClass();
    string connectionString = serializer.SaveToString(ps, null, null);

    Thread thread = new Thread(LoadDataAsync);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start(connectionString);
  }
  else
    LoadData((IFeatureWorkspace)workspace);
}


чтение данных при работе в основном потоке занимает порядка 15-20 секунд (что тоже очень небыстро - в базе всего около 160 тыс не слишком сложных полигонов)
чтение в дополнительном потоке занимает уже даже не на порядок, а раз в 20 больше времени
0 голосов
ответил 06 Апр, 10 от TDenis (42,620 баллов)
Вот быстренько состряпал файлик.
Падения производительности в 20 раз не наблюдаю.
Попробуйте скомпилировать, проверьте на ваших данных.

Единственное, я прогонял на файловой базе, поэтому поменял:
case esriWorkspaceType.esriLocalDatabaseWorkspace:

      wsf = new AccessWorkspaceFactoryClass();
      break;
на
case esriWorkspaceType.esriLocalDatabaseWorkspace:

    wsf = new FileGDBWorkspaceFactoryClass();
    break;


Давайте дальше смотреть.
А вы когда запускаете задачу в фоновом потоке, при этом в основном потоке ничего особо ресурсоёмкого не делаете?
0 голосов
ответил 06 Апр, 10 от TDenis (42,620 баллов)
Забыл сказать, это, конечно же, обычный C# Console Application.
Добро пожаловать на сайт Вопросов и Ответов, где вы можете задавать вопросы по GIS тематике и получать ответы от других членов сообщества.
...