Я только что "заработал" привилегию сохранить устаревшую библиотеку, закодированную на С#, в моей текущей работе.
Эта dll:
- Предоставляет методы для большой старой системы, созданной с помощью Uniface, у которой нет выбора, кроме вызова COM-объектов.
- Служит как ссылка между этой унаследованной системой и другим системным API.
- В некоторых случаях WinForm использует свой интерфейс.
Более визуально, поскольку я понимаю компоненты:
*[Big legacy system in Uniface]*
== [COM] == > [C# Library]
== [Управляемый API] == > *[Big EDM Management System]*
Вопрос в том, что один из методов в этой библиотеке С# слишком длинен для запуска, и я должен "сделать" его асинхронным!
Я привык к С#, но не к COM вообще. Я уже выполнял параллельное программирование, но COM, похоже, добавляет к нему много сложностей, и все мои испытания до сих пор заканчиваются:
- Авария без сообщения об ошибке
- Моя Dll работает только частично (отображает только часть пользовательского интерфейса, а затем закрывается) и до сих пор не дает мне никакой ошибки.
У меня нет идей и ресурсов о том, как обрабатывать потоки в DLL COM, и я был бы признателен за любой намек или помощь.
До сих пор большая часть кода, который я изменил, чтобы сделать мой метод асинхронным:
// 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
, и с помощью этот пример) мне удалось реорганизовать мой код и заставить его работать, но только при вызове из другого приложения Window в С#, а не через 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 и создание интерфейса между системой и службой. Он должен быть более устойчивым..