【发布时间】:2017-09-14 09:55:55
【问题描述】:
我在调用第三方 C++ dll 时遇到问题,我使用 DllImport 将其封装在一个类中以访问其功能。
dll 要求在使用之前打开一个会话,它返回一个整数句柄,用于在执行操作时引用该会话。完成后,必须使用相同的句柄关闭会话。所以我做了这样的事情:
public void DoWork(string input)
{
int apiHandle = DllWrapper.StartSession();
try
{
// do work using the apiHandle
}
catch(ApplicationException ex)
{
// log the error
}
finally
{
DllWrapper.CloseSession(apiHandle);
}
}
我遇到的问题是 CloseSession() 有时会导致有问题的 Dll 在运行线程时抛出错误:
System.AggregateException:发生一个或多个错误。 ---> System.AccessViolationException:试图读或写保护 记忆。这通常表明其他内存已损坏。
我不确定我能做些什么来阻止这个错误,因为它似乎是由以线程方式使用 Dll 引起的——它应该是线程安全的。但是由于我的 CloseSession() 函数除了调用 Dll 的 close 函数之外什么都不做,所以我没有太多的回旋余地来“修复”任何东西。
然而,最终结果是会话没有正确关闭。因此,当该进程再次尝试时,它应该这样做,它会遇到一个打开的会话并不断抛出新的错误。该会话绝对必须关闭。
我不知道如何设计一个更强大的错误处理语句来确保会话始终关闭?
【问题讨论】:
-
我想问题是,错误应该如何“处理”?如果关闭会话从 3rd 方代码中引发错误,并且如果不关闭会话就无法继续,那么下一步怎么办?我的意思是,您可以在该
finally中添加另一个try/catch,但是您将如何实际响应该错误?如果第 3 方工具不起作用,该怎么办? -
如果这是由线程引起的,那么也许您可以通过在 StartSession() 和 CloseSession() 方法调用周围使用 lock(){} 语句来解决此问题。
-
@David 第三方工具失败是间歇性的——当你第二次尝试时,它通常可以工作。我的实际代码目前是一团糟的递归和控制流,试图确保这种情况总是发生。我不愿意添加更多,但如果必须,我必须:(
-
@MattThrower 你有没有实际测试过一次只通过一个线程使用这个不是真正线程安全的第 3 方库?如果你这样做,问题会消失吗?
-
这是 32 位还是 64 位 DLL?句柄通常是指针大小的东西。您可能应该使用 IntPtr 而不是 int 作为句柄类型。
标签: c# multithreading dll error-handling unmanaged