C# 处理方法中的阻塞
C# 处理方法中的阻塞,c#,.net,blocking,synchronous,idisposable,C#,.net,Blocking,Synchronous,Idisposable,Dispose()方法(同步变量)中的阻塞是否会影响GC过程 假设: 没有显式终结器的类 在Dispose中没有真正的资源分配/释放,只是滥用模式在Dispose调用点注入一些代码 到目前为止,我把Dispose理解为一种“正常”方法,它也可能被编译器从一些语法糖结构生成的代码“意外”调用,例如使用(var I=new Something(…){}或使用var I=new Something(…)以及如果使用不适合我们(出于任何原因),我们直接叫它 这意味着,内部的任何阻塞操作都只意味着Di
Dispose()
方法(同步变量)中的阻塞是否会影响GC过程
假设:
- 没有显式终结器的类
- 在
中没有真正的资源分配/释放,只是滥用模式在Dispose
调用点注入一些代码Dispose
Dispose
理解为一种“正常”方法,它也可能被编译器从一些语法糖结构生成的代码“意外”调用,例如使用(var I=new Something(…){}
或使用var I=new Something(…)
以及如果使用不适合我们(出于任何原因),我们直接叫它李>
这意味着,内部的任何阻塞操作都只意味着Dispose
执行点的延迟,对吗
这意味着,GC根本不关心Dispose
,只收集任何实例,而不考虑是否调用Dispose
,对吗
从上面可以看出,在上述条件下,当在Dispose中处理阻塞的实例时,没有任何内存泄漏或GC影响的原因,对吗
此类类别的示例:
class DisposeBlocker : IDisposable
{
private Task localWork;
private Task remoteWork;
...
DisposeBlocker(Task work)
{
remoteWork = work;
}
void Dispose()
{
for (var i = 0; i < 1000000; ++i) {} // CPU Bound
Thread.Sleep(1000); // Should be ok too, right?
Task.Delay(1000).GetAwaiter().GetResult(); // Is this still ok? Thread pools, contexts, similar stuff...
Task.WhenAll(localWork, remoteWork).GetAwaiter().GetResult(); // Same as the previous one, right?
}
}
class-DisposeBlocker:IDisposable
{
私人任务本地工作;
私人任务远程工作;
...
DisposeBlocker(任务工作)
{
远程工作=工作;
}
无效处置()
{
对于(var i=0;i<1000000;++i){}//CPU界
Thread.Sleep(1000);//应该也可以吧?
Task.Delay(1000).GetAwaiter().GetResult();//这还可以吗?线程池,上下文,类似的东西。。。
Task.WhenAll(localWork,remoteWork).GetAwaiter().GetResult();//与前一个相同,对吗?
}
}
正确
如果没有终结器,GC将不关心Dispose
方法
这听起来像是一个巨大的代码气味,但是:如果Dispose
是必要的,我想最好确保在大多数情况下调用它,因为您需要一个终结器。并且终结器在任何情况下都不得阻止或引发异常
Dispose
也无法阻止这两种情况。所以你真的应该避免这种设置。非常正确。值得注意的是,C#8.0引入了一种异步处理模式,它处理了问题中的示例