Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 处理方法中的阻塞_C#_.net_Blocking_Synchronous_Idisposable - Fatal编程技术网

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引入了一种异步处理模式,它处理了问题中的示例