如何在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表达式中传递ref参数?-线程问题

为什么会出现错误

匿名方法的参数范围是匿名方法块

(强调矿(

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));

唯一的问题是,您的过程现在编辑传递对象内部的字段,而不是实际变量,所以您必须检查该字段。