Csharp/C#教程:WCF服务应用程序 – 使用C ++对象调用导致Visual Basic 6.0 DLL文件挂起分享


WCF服务应用程序 – 使用C ++对象调用导致Visual Basic 6.0 DLL文件挂起

我们目前正在移动系统以使用WCF并遇到了一个我们无法弄清楚的问题。 设置是有一个C#DLL文件包装C ++和Visual Basic 6.0 DLL文件。 C#DLL文件具有这两者的包装器,并实例化这两个对象。 初始化C ++对象(从文件中抓取数据),然后将其传递给Visual Basic 6.0对象,该对象使用C ++对象中的数据运行报表。 这一切都是作为WCF服务应用程序发生的,并且在大多数情况下它工作得很好,但是当Visual Basic 6.0代码调用C ++对象中的方法时,整个事情就会挂起。

我只使用一个调用相同C#DLL文件(在WCF之外)的简单应用程序进行测试,并且它可以完美地工作。 因此,WCF和C ++ DLL文件有一些问题,但我们无法弄清楚是什么。 我已经将Visual Basic 6.0 DLL文件更改为使用Run UnattendedStore in Memory (以便能够使用它),但这似乎并不重要。

有没有人有这方面的经验,或者有任何想法为什么会挂? 我的想法是WCF服务以某种方式锁定DLL文件,这就是为什么当Visual Basic 6.0 DLL文件使用它时,它无法访问它,导致它死锁。

C ++ Wrapper

public interface ISummaryWrapper { void LoadInfo(Application info); SummaryApp GetSummary(); } public class SummaryWrapper : ISummaryWrapper { private SummaryApp _summary; public SummaryWrapper() { _summary = new SummaryApp(); } public SummaryWrapper(Application info) { _summary = new SummaryApp(); LoadInfo(info); } public void LoadInfo(Application info) { _summary.Initialize(info); } public SummaryApp GetSummary() { return _summary; } } 

info对象包含有关Summary对象需要生成的内容的信息。 它仅用于Initialize方法。

Visual Basic 6.0对象通过接口加载:

 public void LoadPageObject(Application info) { _pageInfo = new PageInformation(); _pageInfo.oInfo = info; _pageInfo.oSummary = _summary; } 

所以现在Visual Basic 6.0对象PageInformation有了摘要对象。

接下来,我们调用该方法来生成报告:

 _pageInfo.BuildReport(); 

这在Visual Basic 6.0 DLL文件中,并且在代码尝试使用摘要对象时,它会挂起

 // Omitted actual params for brevity, though all the params exist double value = oSummary.GetData(string parm1, string parm2) 

如果我在C#中使用相同的调用,它会将数据拉回来。

 double value = _summary.GetData(string parm1, string parm2); 

再次,当我在WCF之外使用这个包装器时,它会很好地完成代码。 只有当它在WCF中运行时它才会挂起。

这似乎是在MTA中运行的问题,我不确定在IIS上运行的WCF服务应用程序是否可以设置为在STA中运行。 这可能吗?


已解决:我在Stack Overflow问题中找到了答案:

如何制作WCF服务STA(单线程)

这引出了我的文章XXX

基本上,我必须创建一个设置为STA的线程,并在其中运行API(我的C#DLL文件)。 由于我使用TaskFactory运行所有这些(所以我可以取消调用,并运行多个请求),这有点棘手。 现在,我仍然可以在MTA中同时运行多个报告,但每个报告都在STA中运行。 此外,我也不会失去WCF的取消function。

这是代码(我还有一些清理工作):

 public class Builder { public string OperationId { get; set; } public IServiceCallback CallBack { get; set; } public Dictionary Queue { get; set; } public void BuildReport() { OperationContext context = OperationContext.Current; Thread thread = new Thread( new ThreadStart( delegate { using (OperationContextScope scope = new OperationContextScope(context)) { try { CancellationToken token = Queue[OperationId].Token; CallBack.SendStatus(OperationId, Status.Processing); IAPI api = new API(token); api.MessagingEvents += MessageEvent; // Build Report CallBack.SendStatus(OperationId, Status.BuildingReport); if (!api.BuildReport()) return; CallBack.SendStatus(OperationId, Status.Completed); } catch (OperationCanceledException oc) { // Sending this on the method that receives the cancel request, no need to send again } catch (Exception ex) { // May not be able to use callback if it's a Timeout Exception, log error first // TODO: Log Error CallBack.SendMessage(OperationId, MessageType.Error, ex.Message); CallBack.SendStatus(OperationId, Status.Error); } finally { Queue.Remove(OperationId); } } })); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); } } 

我的服务通过以下方式调用:

 // I initialize taskfactory when the service is created, omitting other code for brevity public void BuildReport(ReportRequest request) { CallBack.SendReportStatus(request.OperationId, Status.Received); CancellationTokenSource cancelSource = new CancellationTokenSource(); Queue.Add(request.OperationId, cancelSource); Builder builder = new Builder { OperationId = request.OperationId, CallBack = CallBack, Queue = _queue }; _taskFactory.StartNew(builder.BuildReport, cancelSource.Token); } 

我希望这可以帮助遇到这个问题的任何人!

需要从STA线程运行VB6(COM)。 您的WCF代码可能正在调用一个或多个MTA线程上的VB6组件。 我打赌你的测试(非WCF)应用程序,一个有效的,是一个桌面应用程序。 您需要确保不从任意.NET线程调用VB6组件。

上述就是C#学习教程:WCF服务应用程序 – 使用C ++对象调用导致Visual Basic 6.0 DLL文件挂起分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/949836.html

(0)
上一篇 2021年11月18日
下一篇 2021年11月18日

精彩推荐