Фоновый рабочий инициирует COM-компонент

#c# #com #.net-4.0 #backgroundworker

#c# #com #.net-4.0 #Фоновый рабочий

Вопрос:

Я использую COM-компонент, который работает абсурдно медленно (требуется несколько минут, чтобы предоставить мне запрошенные данные), поэтому, чтобы пользовательский интерфейс оставался отзывчивым, в моем приложении WPF я подумываю об использовании классов Task или BackgroundWorker для создания фонового потока и отключения всех элементов управления в пользовательском интерфейсе для предотвращения любых проблем, таких каккомпонент не является потоковым.

Компонент добавляется в проект просто как стандартная ссылка на COM. Проблема в том, что он просто не работает (включая инициализацию с использованием new) из любого фонового потока. Он отлично работает из потока пользовательского интерфейса. Любые указатели будут оценены.

Комментарии:

1. Да, редко работает. Существуют разные виды «просто не работает», вам нужно быть более конкретным.

2. Возможно, что COM-компонент просто не предназначен для работы, кроме как в потоке пользовательского интерфейса.

Ответ №1:

Вы пытались добавить [STAThread] атрибут в Main() ?

 [STAThread]
static void Main()
{
}
 

Когда применяется атрибут STAThreadAttribute, он изменяет базовое состояние текущего потока на однопоточное.
Не вдаваясь в пространную дискуссию о COM и потоках, этот атрибут обеспечивает механизм связи между текущим потоком и другими потоками, которые могут захотеть связаться с ним через COM.
Этот атрибут обычно автоматически применяется к Main при запуске нового проекта пользовательского интерфейса.


Или (как сказал мне СЛакс) вы можете попробовать:

 Thread t = new Thread(ThreadProc);
t.SetApartmentState(ApartmentState.STA);
....

public void ThreadProc()
{
    // Thread function
}
 

Вы также можете использовать

 bool result = t.TrySetApartmentState(ApartmentState.STA);
 

и проверьте result значение, чтобы убедиться, что ваша попытка была успешной

Комментарии:

1. Это только для Main() . Вам нужно запустить new Thread и вызвать SetApartmentState

2. Спасибо @SLaks: я отредактировал свой пост, чтобы отразить ваше предложение. Как вы думаете, сейчас лучше? 😉

3. Его добавление Main повлияет только на основной поток. ( Main() вероятно, он уже есть в любом случае)

4. @SLaks: да, вы правы (вы всегда правы 😉 ); в любом случае я бы хотел оставить эту часть … если OP хочет вызвать COM-объект прямо из основного потока. Как вы думаете, будет лучше, если я удалю свой ответ, а вы напишете свой? Это будет лучше, чем у меня 😉

5. Ваш ответ достаточно хорош; просто уточните, что [STAThread] делает.