如何在lambda表达式中传递ref参数?-线程问题
本文关键字:参数 ref 问题 线程 lambda 表达式 | 更新日期: 2023-09-27 18:01:41
我有一个要调用的方法。
public void RecordConversation(ref ChannelResource cr)
{
VoiceResource RecordResource = TServer.GetVoiceResource();
RecordResource.MaximumTime = 6000;
RecordResource.MaximumSilence = 6000;
RecordResource.TerminationDigits = "";
}
在线程中调用它
Thread recordThread = new Thread(() => RecordConversation(ref ChanResource));
recordThread.Start();
我们当然会出错。
不能在匿名方法、lambda表达式或查询表达式中使用ref或out参数"ChanResource">
如何修复?
为什么会出现错误
匿名方法的参数范围是匿名方法块。
(强调矿(
lambda表达式本质上与匿名方法相同。
根据文档,参数的范围仅限于其块。
但是CCD_ 1和CCD_。我建议您不要使用ref
,因为默认情况下参数是按值传递的,如果是引用类型,则传递引用的值。
您可以直接修改参数以反映该更改。
您不能使用ref
。看到同样的问题。
话虽如此,您提到的原因(对象很大并且经常使用,我不想以值类型传递它(是无效的。
如果删除ref
,则不会将参数作为值传递。在这里使用ref
不会有任何性能/内存增益。参见参考值。
相反:
Thread recordThread = new Thread(() => RecordConversation(ref ChanResource));
recordThread.Start();
你应该做:
Thread recordThread = new Thread(() => {
VoiceResource RecordResource = TServer.GetVoiceResource();
RecordResource.MaximumTime = 6000;
RecordResource.MaximumSilence = 6000;
RecordResource.TerminationDigits = "";
});
recordThread.Start();
如果不在方法中重新创建此对象,则不必将其作为引用传递。然而,如果你正在重建它,那么你的裁判会有意义:
public void RecordConversation(ref ChannelResource cr)
{
cr = new ChannelResource();
VoiceResource RecordResource = TServer.GetVoiceResource();
RecordResource.MaximumTime = 6000;
RecordResource.MaximumSilence = 6000;
RecordResource.TerminationDigits = "";
}
通过ref创建对象会将调用程序创建为新对象。
由于闭包环境的原因,无法在lambda表达式中发送ref。C#在运行时编译匿名表达式。如果你试图向你的封闭代码发送一个ref,那么编译器必须找到一种方法来访问你的ref对象,这是没有意义的。在这里,您可以检查闭包:http://en.wikipedia.org/wiki/Closure_(computer_science(
public class ThreadParams
{
public ChannelResource ChanResource;
public ThreadParams(ChannelResource chanResource) {
ChanResource = chanResource; }
}
public void ThreadProc(Object obj)
{
RecordConversation(ref ((ThreadParams)obj).ChanResource);
}
Thread recordThread = new Thread(ThreadProc);
recordThread.Start(new ThreadParams(ChanResource));
唯一的问题是,您的过程现在编辑传递对象内部的字段,而不是实际变量,所以您必须检查该字段。