c# - 抑制对象终结,直到其他线程运行

标签 c# .net

假设我在类中有一些代码,其中一个方法立即返回结果,但在此之前调用后台任务。

class CalculationPolicy 
{
    private readonly IRequestContext _reqContext;

    public CalculationPolicy(IRequestContext reqContext)
    {
       _reqContext = reqContext;
    }

    public ProcessResult Process(object model) 
    {
        var response = new ProcessResult();

        // some synchronous processing ... 
          ............................

        // notifications go into other thread
        Task.Run(() => NotifyCallback(model));

        return response;
    }

    private void NotifyCallback(object model)
    {
       // some notification logic
       // that uses a field [_reqContext]
       string email = _reqContext.GetEmailFromClaims();
    }
}

我想知道垃圾收集器是否知道我的类的实例不应该最终确定,直到方法 NotifyCallback 在其他线程上完成,这样我的对象的状态就不会被垃圾收集器影响

最佳答案

当没有更多引用指向该对象时,该对象将被收集。安排任务时:

Task.Run(() => NotifyCallback(model));

委托(delegate)具有对您的对象的隐式引用,因此在任务运行之前不会收集它。

但要挑剔一下,你的问题具体是:

I wonder if the Garbage Collector knows that the instance of my class SHOULD NOT be finalized until the method NotifyCallback is finished on other thread

如果您的对象停止引用 this,则可能会在 NotifyCallback 中间收集该对象。例如:

private void NotifyCallback(object model)
{
   // some notification logic
   // that uses a field [_reqContext]
   string email = _reqContext.GetEmailFromClaims();

   // Do some stuff with email but do not access any field
   // From this point, the object can be collected at any time
   Console.WriteLine(email);   

   Console.WriteLine("Done");
}

从技术上讲,您的对象可以在 string email = _reqContext.GetEmailFromClaims(); 之后的任何时候收集。这应该不是问题,因为您不再使用类中的任何字段。在极少数情况下(通常是与 native 代码进行互操作时),您可以使用 GC.KeepAlive 来保存引用并人为地延长对象的生命周期:

private void NotifyCallback(object model)
{
   // some notification logic
   // that uses a field [_reqContext]
   string email = _reqContext.GetEmailFromClaims();

   // Do some stuff with email but do not access any field
   Console.WriteLine(email);   

   Console.WriteLine("Done");

   GC.KeepAlive(this); // The GC won't collect the object before this line
}

但实际上在大多数情况下你应该没问题。

关于c# - 抑制对象终结,直到其他线程运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54291981/

相关文章:

c# - linq 中计算列表百分比的最佳方法是什么?

c# - 在进程中创建新的应用程序域时发出通知

.net - Visual Studio c++ 2010 中的参数

c# - 如何使用 LINQ 对序列中的相同值进行分组?

.net - 从 NHibernate 映射生成数据库模式

c# - WPF:哪种解决方案?带有关闭按钮和新选项卡按钮的 TabControl

c# - 我如何在核心 web api 中测试我的数据注释字段?

C# Xamarin - 使用 SetValueForKey 将数据绑定(bind)到 UICollectionViewCell

c# - .NET 私​​钥 Rsa 加密

c# - 映射两个具有不同 namespace 的相同枚举