Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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# Resharper:隐式捕获闭包:此_C#_.net_Resharper - Fatal编程技术网

C# Resharper:隐式捕获闭包:此

C# Resharper:隐式捕获闭包:此,c#,.net,resharper,C#,.net,Resharper,我从Resharper那里得到这个警告(“隐式捕获闭包:this”):这是否意味着这段代码以某种方式捕获了整个封闭对象 internal Timer Timeout = new Timer { Enabled = false, AutoReset = false

我从Resharper那里得到这个警告(“隐式捕获闭包:this”):这是否意味着这段代码以某种方式捕获了整个封闭对象

    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;
        }
    }
内部计时器超时=新计时器
{
启用=错误,
自动重置=错误
};
公共任务响应任务
{
得到
{
var tcs=new TaskCompletionSource();
Timeout.appeated+=(e,a)=>tcs.SetException(新的TimeoutException(“timeat”+a.SignalTime));
如果(_response!=null)tcs.SetResult(_response);
else ResponseHandler+=r=>tcs.SetResult(_response);
返回tcs.Task;
}
}
我不知道它是如何或为什么这样做的——它应该捕获的唯一变量是TaskCompletionSource,这是有意的。这真的是一个问题吗?如果是,我该如何着手解决


编辑:警告出现在第一个lambda上(超时事件)。

看起来
\u response
是类中的一个字段

从lambda中引用
\u响应
将在闭包中捕获
,并在lambda执行时读取
此。\u响应


为了防止出现这种情况,您可以将
\u response
复制到局部变量,然后使用它。请注意,这将导致它使用
\u response的当前值,而不是其最终值。

问题似乎不是我认为的那一行

问题是在父对象中有两个lambda引用字段:编译器生成一个包含两个方法的类和一个对父类的引用(
this

我认为这将是一个问题,因为对
this
的引用可能会留在TaskCompletionSource对象中,从而阻止它被GCed。至少我在这个问题上的发现表明了这一点

生成的类看起来像这样(显然名称将不同且不可命名):

我认为编译器这样做的原因可能是效率,因为两个lambda都使用
TaskCompletionSource
;但是现在,只要对其中一个lambda的引用仍然被引用,对
请求
对象的引用也会被保留

不过,我还没有找到解决这个问题的办法

编辑:很明显,我在写这篇文章的时候并没有考虑到这一点。我通过如下更改方法解决了问题:

    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;
        }
    }
公共任务任务响应
{
得到
{
var tcs=new TaskCompletionSource();
Timeout.appeated+=(e,a)=>tcs.SetException(新的TimeoutException(“timeat”+a.SignalTime));
如果(_response!=null)tcs.SetResult(_response);
else ResponseHandler+=tcs.SetResult;//事件传递一个Response(derp)类型的对象,然后将该对象分配给_Response字段。
返回tcs.Task;
}
}

我应该提到,警告出现在第一个lambda(超时事件)上,而不是第二个lambda上。此外,您所描述的是对_响应的捕获,而不是“this”reference@user1447072:将回答中的
\u response
替换为
Timeout
),但它不应该捕获超时变量?(lambda中没有任何地方引用它)。@AaronMaslen#1:否。Lambdas捕获变量或参数,例如
this
<代码>\u response
实际上是
这个。\u response
,它捕获了
这个
。我记得,我不认为它捕获了
这个
——从某种意义上说,编译器生成的类只包含
response
类型的单个字段,这是对
这个的引用。\u response
。但是,必须检查拆卸以确认。无论如何,这是一个没有实际意义的问题,因为这一行不是引起警告的那一行。将if语句或超时事件行移动到单独的方法会删除警告,但我觉得这不是一个理想的解决方案
    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;
        }
    }