Kei*_*ons 3 c# idisposable using misuse
我想创建一个内部消息系统,可以告诉我一些代码被调用的持续时间.我在考虑易用性,以使SystemMessage类实现IDisposable.
我会在SystemMessage的构造函数中设置一个时间戳,如果调用了Dispose,我可以计算出持续时间.
问题是我不希望GC对象.我希望它作为MessageCollection的一部分留在身边.
在C#中是否有另一个构造可以在没有踩到IDisposable的预期功能的情况下为我提供Using语句的可用性.
Using (message = Collection.CreateNewMessage("FileDownlading"))
{
// I wonder how long it is taking me to download this file in production?
// Lets log it in a message and store for later pondering.
WebClass.DownloadAFile("You Know This File Is Great.XML");
}
// we fell out of the using statement, message will figure out how long
// it actually took to run.
// This was clean and easy to implement, but so wrong?
Run Code Online (Sandbox Code Playgroud)
问题是我不希望GC对象.我希望它作为MessageCollection的一部分留在身边.
调用Dispose不会导致对象被GC控制 - 当GC执行扫描并且没有任何内容引用它时会发生这种情况.如果您仍然通过MessageCollection引用该对象,它将会坚持下去.
Dispose可以防止它被终结,但由于你没有使用Dispose来清理资源,你将没有Finalizer而你也不会关心.
所以,真正唯一的问题是令人困惑的语义围绕让你的calss实现IDisposable,即使没有资源可以处理.
就个人而言,我不认为这是一个问题.如果消费者呼叫Dispose,那么很好 - 他们得到时间记录.如果他们不这样做,那么他们就不会获得itme邮票,而最糟糕的情况是他们会得到一个FxCop违规行为.
然而,它有点不直观 - 所以如果这是供公众使用的话,我建议提供更多可发现的替代方案,例如:
// C# 3+ lambda syntax
Collection.CreateNewMessage("FileDownlading", () => {
// I wonder how long it is taking me to download this file in production?
// Lets log it in a message and store for later pondering.
WebClass.DownloadAFile("You Know This File Is Great.XML");
});
// C# 2 anonymous delegate syntax
Collection.CreateNewMessage("FileDownlading", delegate() {
// I wonder how long it is taking me to download this file in production?
// Lets log it in a message and store for later pondering.
WebClass.DownloadAFile("You Know This File Is Great.XML");
});
// Method
void CreateNewMessage(string name, Action action) {
StopWatch sw = StopWatch.StartNew();
try {
action();
} finally {
Log("{0} took {1}ms", name, sw.ElapsedMilliseconds);
}
}
Run Code Online (Sandbox Code Playgroud)
这将运行和时间一个行动代表.
| 归档时间: |
|
| 查看次数: |
540 次 |
| 最近记录: |