将参数传递给Task.Factory.StartNew
给出以下代码:
string injectedString = "Read string out of HttpContext"; Task.Factory.StartNew(() => { MyClass myClass = new MyClass(); myClass.Method(injectedString); }
这是将字符串传递给任务/线程的最佳方法吗?
我对这种方法的担忧是:
这是在Asp.Net网络服务中,如果它很重要并且是一个火灾和忘记类型的线程,我不是在等待任何类型的响应。
我的字符串实际上是从HttpContext
读出来的,这是我以这种方式注入它的一个原因(Thread无法访问调用线程HtppContext
)
您的lambda将被提升到编译器生成的类中。 injectedString
变量将成为该类的字段。
因此,当生成的类超出范围(基本上在lambda的最后)时,它将被垃圾收集,并且GC决定执行集合。
回应你的评论:
没有重复。 编译器转为:
string injectedString = "Read string out of HttpContext"; Task.Factory.StartNew(() => { MyClass myClass = new MyClass(); myClass.Method(injectedString); }
进入这个:
CompilerGeneratedClass c1 = new CompilerGeneratedClass(); c1.injectedString = "Read string out of HttpContext"; // call delegate here.
还要记住:字符串是在CLR中实现的。 即使代码是重复的,字符串文字也会在池中实现。 您基本上只有一个本地WORD大小的引用重复指向字符串(仅限字符串文字..)
您应该使用Task.Factory.StartNew(Action
重载将状态传递给新任务。
Task.Factory.StartNew((object myState) => { var i = (int)myState; //Do calculations... var x = i + 10; }, 10);
如果你担心在myClass.Method(injectedString);
之前myClass.Method(injectedString);
可能是“垃圾收集” myClass.Method(injectedString);
跑?
答案是否定的 。 您不必担心这一点,因为在lambda
关闭时, lambda
不再是局部变量。 它将成为新编译器生成的类中的一个字段。
如果您担心垃圾收集器会在合适的时间收集它吗? 答案是肯定的 ,当该类的实例超出范围且在托管代码中没有引用它时,它将会执行。 在Task
完成并超出范围后,肯定会发生这种情况。
上述就是C#学习教程:将参数传递给Task.Factory.StartNew分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/983013.html