相关疑难解决方法(0)

这个闭包组合行为是C#编译器的错误吗?

我正在调查一些奇怪的对象生命周期问题,并遇到了C#编译器的这种非常令人费解的行为:

考虑以下测试类:

class Test
{
    delegate Stream CreateStream();

    CreateStream TestMethod( IEnumerable<string> data )
    {
        string file = "dummy.txt";
        var hashSet = new HashSet<string>();

        var count = data.Count( s => hashSet.Add( s ) );

        CreateStream createStream = () => File.OpenRead( file );

        return createStream;
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器生成以下内容:

internal class Test
{
  public Test()
  {
    base..ctor();
  }

  private Test.CreateStream TestMethod(IEnumerable<string> data)
  {
    Test.<>c__DisplayClass1_0 cDisplayClass10 = new Test.<>c__DisplayClass1_0();
    cDisplayClass10.file = "dummy.txt";
    cDisplayClass10.hashSet = new HashSet<string>();
    Enumerable.Count<string>(data, new Func<string, bool>((object) cDisplayClass10, __methodptr(<TestMethod>b__0)));
    return new …
Run Code Online (Sandbox Code Playgroud)

c# lambda closures .net-4.6

16
推荐指数
2
解决办法
544
查看次数

在匿名代表中捕获的私有字段

class A
{
   public event EventHandler AEvent;
}
class B
{
   private A _foo;
   private int _bar;

   public void AttachToAEvent()
   {
      _foo.AEvent += delegate()
      {
         ...
         UseBar(_bar);
         ...
      }
   }
} 
Run Code Online (Sandbox Code Playgroud)

由于delegate捕获变量this._bar,它是否隐含地保持实例B?将B通过事件处理程序和捕获的变量引用实例A吗?

如果_bar是方法的局部变量,它会有所不同AttachToAEvent吗?

因为在我的情况下,A生命的实例远远长于并且远小于实例B,我担心通过这样做导致"内存泄漏".

c# closures memory-leaks anonymous-methods object-lifetime

12
推荐指数
2
解决办法
1651
查看次数

任务中的秒表似乎是所有任务的附加,想要测量任务间隔

我正在循环运行并以下列方式开始执行任务:

var iResult = new List<Task>();
foreach(var i in myCollection)
{
    var task = Task.Factory.StartNew(() =>
                    DoSomething(), TaskCreationOptions.LongRunning);
    task.ContinueWith(m => myResponseHandler(m.Result));
    iResult.Add(task);
}
Run Code Online (Sandbox Code Playgroud)

在我的DoSomething()方法中,我有一个计时器:

public static myMsg DoSomething()
{
    var timer = System.Diagnostics.Stopwatch.StartNew();
    DoLongRunningTask(); //If it matters this hits a REST endpoint (https)
    timer.Stop();

    return new myMsg(timer.ElaspedMilliseconds);
}
Run Code Online (Sandbox Code Playgroud)

当我遍历我的列表时,myMsgElaspedMilliseconds似乎完全是加法的 - 第一个上的ElaspedMilliseconds可能是300,但最后一个可能是50000(50秒) - 这实际上是整个事情所需的大致时间运行(由另一个计时器测量).

c# synchronization closures stopwatch task-parallel-library

6
推荐指数
1
解决办法
1774
查看次数