我刚刚“赢得”了在当前工作中维护用 C# 编码的遗留库的特权。
这个dll:
- 公开使用 Uniface 构建的大型遗留系统的方法,除了调用 COM 对象之外别无选择。
- 充当此遗留系统与另一个系统的 API 之间的链接。
- 在某些情况下,使用 WinForm 作为其 UI。
更直观地,据我了解这些组件:
*[Big legacy system in Uniface]*
==[COM]==> [C# Library]
==[托管API]==> *[Big EDM Management System]*
问题是:此 C# 库中的方法之一运行时间太长,我"should"使其异步!
我习惯了 C#,但根本不习惯 COM。我已经完成了并发编程,但 COM 似乎增加了很多复杂性,到目前为止我的所有试验都以以下任一方式结束:
- 完全没有错误消息的崩溃
- 我的 Dll 仅部分工作(仅显示其 UI 的一部分,然后关闭),并且仍然没有给我任何错误
我没有关于如何处理 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
,并在帮助下这个例子 http://blogs.msdn.com/b/mattdotson/archive/2006/02/13/531315.aspx)我能够重构我的代码并使其正常工作,但仅限于从 C# 中的另一个 Window 应用程序调用时,而不是通过 COM。
当我调用该函数时,旧系统遇到一个相当模糊的错误,并且没有提供有关崩溃的任何详细信息。
更新2:
我的试验中的最新更新:当从测试项目进行调用时,我设法使多线程工作,并且not来自统一系统。
经过多次试验,我们倾向于认为我们的遗留系统在当前配置中不能很好地支持多线程。但这不再是问题的重点了:)
以下是似乎有效的代码摘录:
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 服务中并在系统和服务之间创建接口。应该更可持续..