我正在使用第三方程序集为我的项目提供sftp功能,如下所示。 多个线程需要实现此功能,因此第三方程序集将在静态帮助程序类中使用。
第三方程序集运行良好,除非遇到异常错误情况,例如: sftp服务器存在,但我试图将文件放入的目录被删除。 当发生这种情况时,会抛出一个有效的异常,但是看起来间歇性的第三部分程序集没有正确清理,因为没有新的客户端实例可以正常工作。
static readonly object _locker = new object();
static void WorkerMethodCalledByThread()
{
lock(_locker)
{
var client = new ThirdPartyAssembly();
bool hasConnection = false;
try
{
client.Connect("some connection details");
hasConnection = true;
// do some work -
//but if an issue happens here then no new instances of ThirdPartAssembly work
}
catch(Exception e)
{
Logger.LogError(e);
}
finally
{
if (hasConnection) { client.Close(); }
}
}
}
我没有办法让第三方程序集发生变化,所以我正在寻找的是一种处理它可能采取的任何资源的方法。但是,被调用的第三方类本身并没有实现IDisposable。
那么......我想弄清楚是否有可能释放第三方使用的资源?
我能想到的两种可能的方法是
1:添加一个包装类,它以第三方类为基类&它也实现了IDisposable(如下所示) - 但是我很确定这不会清理基类
2:对第三方类使用WeakReference(如下所示) - 但我不知道这是否有效
包装类
public class WrapperClass : ThirdPartyClass, IDisposable
{
~WrapperClass()
{
Dispose();
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
的WeakReference
static readonly object _locker = new object();
static void WorkerMethodCalledByThread()
{
lock(_locker)
{
var client = new WeakReference(new ThirdPartyAssembly());
bool hasConnection = false;
try
{
((ThirdPartyAssembly)client.Target).Connect("some connection details");
hasConnection = true;
// do some work -
//but if an issue happens here then no new instances of ThirdPartAssembly work
}
catch(Exception e)
{
Logger.LogError(e);
}
finally
{
if (hasConnection) { ((ThirdPartyAssembly)client.Target).Close(); }
}
}
}
答案 0 :(得分:1)
WeakReference
的问题是:
同时仍然允许通过垃圾回收来回收该对象。
它并不能保证GC能够实现它,因为它显然不能在内部很好地管理自己。
更好的方法是以类为基础并实现IDisposable
。这将允许您在using
语句中利用您的包装器。但是,需要注意的是,并且实际上没有办法绕过它,你将不得不使用Reflection
深入研究这个类并进行清理。
这会占用很多断点,并在Watch
窗口进行大量挖掘,但你可以完成它!