Сделайте мой вызов COM-сборки асинхронным
Я только что «заработал» привилегию поддерживать устаревшую библиотеку, написанную на C #, на моей текущей работе.
Это dll:
Объявляет методы для большой унаследованной системы, созданной с помощью Uniface, у которой нет другого выбора, кроме вызова COM-объектов.Служит связующим звеном между этой унаследованной системой и API другой системы.В некоторых случаях использует WinForm для своего пользовательского интерфейса.Более наглядно, как я понимаю компоненты:
*[Big legacy system in Uniface]*
== [COM] ==> [C# Library]
== [Управляемый API] ==> *[Big EDM Management System]*
Вопрос: один из методов в этой библиотеке C # занимает слишком много времени, и я"должен" сделать это асинхронным!
Я привык к C #, но совсем не к COM. Я уже выполнил параллельное программирование, но COM, кажется, добавляет ему много сложности, и все мои испытания до сих пор заканчиваются либо:
Авария без сообщения об ошибке вообщеМой Dll только частично работает (отображает только часть своего пользовательского интерфейса, а затем закрывается), и все еще не дает мне никакой ошибки вообщеУ меня нет идей и ресурсов о том, как обрабатывать потоки в COM-DLL, и я был бы признателен за любую подсказку или помощь.
До сих пор большую часть кода я изменил, чтобы сделать мой метод асинхронным:
// my public method called by the external system
public int ComparedSearch(string application, out string errMsg) {
errMsg = "";
try {
Action<string> asyncOp = AsyncComparedSearch;
asyncOp.BeginInvoke(application, null, null);
} catch (ex) {
// ...
}
return 0;
}
private int AsyncComparedSearch(string application) {
// my actual method doing the work, that was the called method before
}
Любая подсказка или полезный ресурс будет оценен. Спасибо.
ОБНОВЛЕНИЕ 1:
Следующие ответы и подсказки ниже (особенно оSynchronizationContext
и с помощьюэтот примерЯ смог реорганизовать свой код и заставить его работать, но только при вызове из другого приложения Windows в C #, а не через COM. Устаревшая система сталкивается с довольно неясной ошибкой, когда я вызываю функцию, и не дает никаких подробностей о сбое.
ОБНОВЛЕНИЕ 2:
Последние обновления в моих испытаниях: мне удалось заставить многопоточность работать, когда звонки сделаны из тестового проекта, ине изСистема Uniface, После нескольких испытаний мы склонны думать, что наша унаследованная система не поддерживает хорошо многопоточность в своей текущей конфигурации. Но это уже не вопрос вопроса :)
Вот фрагмент кода, который, кажется, работает:
string application;
SynchronizationContext context;
// my public method called by the external system
public int ComparedSearch(string application, out string errMsg) {
this.application = application;
context = WindowsFormsSynchronizationContext.Current;
Thread t = new Thread(new ThreadStart(AsyncComparedSearchAndShowDocs));
t.Start();
errMsg = "";
return 0;
}
private void AsyncComparedSearch() {
// ANY WORK THAT AS NOTHING TO DO WITH UI
context.Send(new SendOrPostCallback(
delegate(object state)
{
// METHODS THAT MANAGE UI SOMEHOW
}
), null);
}
Сейчас мы рассматриваем другие решения, помимо изменения этой сборки COM, такие как инкапсуляция этой библиотеки в службе Windows и создание интерфейса между системой и службой. Это должно быть более устойчивым ..