#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]
делает.