【发布时间】:2013-06-17 12:16:33
【问题描述】:
我处于清理非托管资源是关键部分的情况。为了解决这个问题,我改变了这个......
void SomeMethod()
{
//work
using (var doc = SpreadsheetDocument.Open(results.FileName, true))
{
//use doc.
}
}
到这个...
public static readonly object Locker = new object();
void SomeMethod()
{
//work
{//scoping doc
var doc = SpreadsheetDocument.Open(results.FileName, true);
try
{
//use doc
//At some point wrapping a critical section via lock(Locker)
}
finally
{
lock (Locker)
{
if (doc != null) ((IDisposable)doc).Dispose();
}
}
}
}
我相信,这是一个丑陋而脆弱的解决方案。所以,我把它改成了下面的……
public static readonly object Locker = new object();
void SomeMethod()
{
//work
CustomUsingWithLocker(SpreadsheetDocument.Open(results.FileName, true), Locker, doc =>
{
//use doc
//At some point wrapping a critical section via lock(Locker)
});
}
public static void CustomUsingWithLocker<T>(T resource, object locker, Action<T> body)
where T : class, IDisposable
{
try
{
body(resource);
}
finally
{
lock (locker)
{
if (resource != null) resource.Dispose();
}
}
}
此自定义解决方案是否可靠?我可以改进它吗?是否保证释放任何非托管资源,例如内置的 Using 语句?
【问题讨论】:
-
当文档不是共享对象时,为什么要使用锁来保护文档?
-
在我的 customUserWithLocker 中,doc 用于创建一个 excel 文档。如果在此期间正在处理不同的文档,则会引发超时异常。通过锁定 excel 文档创建并锁定 dispose 调用,永远不会发生超时预期。我相信文件流是在文档之间共享的。
-
使用来自 ASP.NET 的 Office Interop 或其他服务器技术是一个可怕的想法。这些 API 是为在桌面应用程序中使用而编写的,用于自动化 Office(一套桌面应用程序)。服务器应用程序在很多方面都不同,这使得在其中使用 Office Interop 成为一个非常非常糟糕的主意。它也不受 Microsoft 支持,并且可能违反您的 Office 许可证。见Considerations for server-side Automation of Office
标签: c# .net multithreading generics using-statement