ReSharper的:隐式捕获封:这 [英] Resharper: Implicitly captured closure: this

查看:176
本文介绍了ReSharper的:隐式捕获封:这的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到这样的警告(蕴捕获封:这种)从ReSharper的:这是否意味着在某种程度上这code是捕获整个封闭对象

I am getting this warning ("Implicity captured closure: this") from Resharper: does this mean that somehow this code is capturing the entire enclosing object?

    internal Timer Timeout = new Timer
                            {
                                Enabled = false,
                                AutoReset = false
                            };
    public Task<Response> ResponseTask
    {
        get
        {
            var tcs = new TaskCompletionSource<Response>();

            Timeout.Elapsed += (e, a) => tcs.SetException(new TimeoutException("Timeout at " + a.SignalTime));

            if (_response != null) tcs.SetResult(_response);
            else ResponseHandler += r => tcs.SetResult(_response);
            return tcs.Task;
        }
    }

我不知道怎样和为什么它是这样做的 - 它应该是捕捉唯一的变量是TaskCompletionSource,这是故意的。这实际上是一个问题,我将如何去解决它,如果它是什么?

I'm not sure how or why it's doing so - the only variable it should be capturing is the TaskCompletionSource, which is intentional. Is this actually a problem and how would I go about solving it if it is?

编辑:警告是在第一拉姆达(超时事件)

The warning is on the first lambda (the Timeout event).

推荐答案

看来这个问题不是我认为这是行了。

It seems that the problem isn't the line I think it is.

现在的问题是,我有两个lambda表达式引用父对象的字段:编译器生成的类有两个方法,并引用父类()。

The problem is that I have two lambdas referencing fields in the parent object: The compiler generates a class with two methods and a reference to the parent class (this).

我认为这将是一个问题,因为参照可能停留在在TaskCompletionSource对象,$ P $被GCed pventing它。至少这就是我发现在这个问题上表明。

I think this would be a problem because the reference to this could potentially stay around in the TaskCompletionSource object, preventing it from being GCed. At least that's what I've found on this issue suggests.

生成的类会是这个样子(显然名称将是不同的,不能发音):

The generated class would look something like this (obviously names will be different and unpronounceable):

class GeneratedClass {
    Request _this;
    TaskCompletionSource tcs;

    public lambda1 (Object e, ElapsedEventArgs a) {
        tcs.SetException(new TimeoutException("Timeout at " + a.SignalTime));
    }

    public lambda2 () {
        tcs.SetResult(_this._response);
    }
}

在编译器这样做的原因可能是效率,我想,作为 TaskCompletionSource 都使用lambda表达式;但现在只要一提到这些lambda表达式中的一个仍然被引用的参考要求对象也保持不变。

The reason the compiler does this is probably efficiency, I suppose, as the TaskCompletionSource is used by both lambdas; but now as long as a reference to one of those lambdas is still referenced the reference to Request object is also maintained.

我还没有接近搞清楚如何避免此问题,虽然。

I'm still no closer to figuring out how to avoid this issue, though.

编辑:很明显我并没有通过这一想,当我在写它。我改变了这样的方法解决了这个问题:

I obviously didn't think through this when I was writing it. I solved the problem by changing the method like this:

    public Task<Response> TaskResponse
    {
        get
        {
            var tcs = new TaskCompletionSource<Response>();

            Timeout.Elapsed += (e, a) => tcs.SetException(new TimeoutException("Timeout at " + a.SignalTime));

            if (_response != null) tcs.SetResult(_response);
            else ResponseHandler += tcs.SetResult; //The event passes an object of type Response (derp) which is then assigned to the _response field.
            return tcs.Task;
        }
    }

这篇关于ReSharper的:隐式捕获封:这的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆