Question

I have a method to be called.

public void RecordConversation(ref ChannelResource cr)
{
    VoiceResource RecordResource = TServer.GetVoiceResource();
    RecordResource.MaximumTime = 6000;
    RecordResource.MaximumSilence = 6000;
    RecordResource.TerminationDigits = "";
}

To call it in a thread

Thread recordThread = new Thread(() => RecordConversation(ref ChanResource));
recordThread.Start();

Of course we get an error.

Cannot use ref or out parameter 'ChanResource' inside an anonymous method, lambda expression, or query expression

How to fix it?

Was it helpful?

Solution 2

You can't use ref. See this very same question.

That being said, the reason you mentioned (The object is big and used often, I don't want to pass it in value type) is not valid.

You won't pass your parameter as value if you remove ref. There won't be any performance/memory gain to use ref here. See value vs reference.

OTHER TIPS

Why that error?

The scope of the parameters of an anonymous method is the anonymous-method-block.

(Emphasis mine)

lambda expressions are essentially the same as anonymous method.

As per the doc, the scope of the parameters is limited to its block.

But ref and out are outside the scope and hence that error. I recommend you not to use ref, as parameters are by default passed by value, and in case of reference type, the value of the reference is passed.

You can modify the parameter directly to reflect that change.

Instead:

Thread recordThread = new Thread(() => RecordConversation(ref ChanResource));
recordThread.Start();

You should do:

Thread recordThread = new Thread(() => {
    VoiceResource RecordResource = TServer.GetVoiceResource();
    RecordResource.MaximumTime = 6000;
    RecordResource.MaximumSilence = 6000;
    RecordResource.TerminationDigits = "";
});
recordThread.Start();

You don't have to pass this object as a reference if you are not recreating it in your method. If you are recreating it however than your ref would make sense:

public void RecordConversation(ref ChannelResource cr)
{
    cr = new ChannelResource();
    VoiceResource RecordResource = TServer.GetVoiceResource();
    RecordResource.MaximumTime = 6000;
    RecordResource.MaximumSilence = 6000;
    RecordResource.TerminationDigits = "";
}

Creating an object by ref causes the caller to be created as a new object.

You cannot send ref in lambda expressions because of the closure environment. C# compiles the anonymous expressions in runtime. If you try to send a ref to your closured code, then the compiler has to find a way to reach out your ref object which doesn't make sense. Here you can check the closures: 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));

The only problem is that your procedure now edits field inside passed object, not the actual variable, so you must check that field.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top