Click here to Skip to main content
13,898,332 members
Rate this:
 
Please Sign up or sign in to vote.
See more:
Hi all!
I want to pass reference parameter to thread.
Code snippet:
private void Start(ref TcpClient handler)
{
  ClientThread = new Thread(delegate() { HandleClientComm(ref handler); });
  ClientThread.Start( handler);
}

But it writes to me:
"Cannot use ref or out parameter inside an annonymous method, lambda expression, query expression"

Or how to keep reference(not value) to the variable?

Who could help me?
Posted
Updated 9-Feb-11 19:43pm
v4
Comments
JF2015 10-Feb-11 0:45am
   
Edited to add code formatting.
   
Thank you for interesting question. Is is not very simple, my 5.
Please see my answer -- it covers all you may need.
Please ask further questions
--SA
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

Good question. First to think about: do you really need to? There is much better method: to wrap a thread and pass this. After that, the thread accesses anything in the class. Isn't that nice?

internal class ThreadWrapper {

    internal ThreadWrapper(/*..*/) {
        /* pass whatever needed from out side */
        Thread = new System.Threading.Thread(Body); //don't tell my it is illegal!
    } //ThreadWrapper

    internal void Start() { this.Thread.Start(); }
    internal void Abort() { this.Thread.Abort(); }

    //and so on...

    void Body() {
        if (this.SomeByRefParameter == null) //can read
            this.SomeByRefParameter = new System.Text.StringBuilder(); //can modify
        //why? because this member is non-static, "this" parameter is used
        //...
    } //Body

    object SomeByRefParameter;
    System.Threading.Thread Thread;

} //class ThreadWrapper


Can you see what's going on? We managed to run non-static (instance) method as a thread start point. As this is an instance method, Body has hidden parameter called this; it is used to pass an instance of the ThreadWrapper. As we have the instance, we can access any members of this instance (shown on example of SomeByRefParameter). You can have other methods of the wrapper accessible from outside and pass any parameter using by value of by reference methods. Don't forget to use synchronization primitives, such as lock.

Don't be afraid; this method of starting thread is not very well documented, but it is much more reliable than starting point with parameter because type casting is not required.

—SA
   
Comments
JF2015 10-Feb-11 1:18am
   
Good alternative solution.
   
Thank you very much, but how it is alternative? I mean, there is no way to pass by ref except this one, in my opinion. If you know another way, that way will be alternative...
--SA
Albin Abel 15-Apr-11 15:36pm
   
Right solution. My 5
Sergey Alexandrovich Kryukov 15-Apr-11 15:55pm
   
Thank you, Albin.
By the way, it renders parametrized thread start pretty much useless, as it requires type cast for limited functionality.
--SA
NuttingCDEF 4-May-11 16:20pm
   
Good method - 5.
   
Thank you very much.
--SA
Santosh K. Tripathi 31-Jul-15 5:09am
   
Thanks. i was looking for this.

I am unable to use this class. could you help me.

My code is


MemoryStream[] arrBmpImages;
int K=0;

protected void GetPNGScreenShots()
{
arrBmpImages = new MemoryStream[CountdtPDF];
for (int i = 0; i < CountdtPDF; i++)
{
Thread_StartForImages(ref arrBmpImages);
k++;
}

}

private void Thread_StartForImages(ref MemoryStream[] arrBmpImages)
{
Thread m_thread = new Thread(Thread_CaptureImages);
m_thread.SetApartmentState(ApartmentState.STA);
m_thread.Start(arrBmpImages);
m_thread.Join();
}


Private void Thread_CaptureImages(ref MemoryStream[] arrBmpImages)
{
System.Drawing.Bitmap bmpImage;
bmpImage = // get images via http://www.codeproject.com/Articles/95439/Get-ASP-NET-C-Website-Thumbnail-Screenshot

using (MemoryStream ms = new MemoryStream())
{
bmpImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
arrBmpImages[k] = ms;
}
}

Now i will use arrBmpImages[] to create PDF or PPT

How i can do it by using you code. i tried but not able to do. Please help.
   
"I was unable..." is not informative. The code sample is for example; you have to understand the idea. Any questions?
—SA
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 4

The problem is that you are attempting to pass a ref variable to an anonymous method. Here is why that is a problem:
Start(ref handler);
handler.DoSomething();
// handler could change here.
handler.DoSomething();

If you pass in an instance by reference to your function and that function passes that reference variable to an anonymous method, that anonymous method could then be executed in a different thread, which would cause the variable reference to change at an undetermined time (such as when the comment in the above code is reached). Since the passing by "ref" is only supposed to change the variable reference when you return from the method call, this functionality is invalid. Here is one way you might get around that (uses a temporary variable):
private void Start(ref TcpClient handler)
{
  var handler2 = handler;
  ClientThread = new Thread(delegate() { HandleClientComm(ref handler2); });
  ClientThread.Start();
  // ClientThread.Join();   // Uncomment this line to ensure HandleClientComm has finished running.
  handler = handler2; // handler2 may or may not have changed by now.
}

That may cause unintended side effects, but at least your code will compile.
   
v2
Comments
IllidanS4 15-Jun-15 14:13pm
   
More problematic than having a variable changed at undetermined time is the lifetime of the variable. When the method ends, the stack frame will be released, and so the reference would be invalid in the created thread, which is inacceptable, of course.
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

Pass Ref Parameter[^] will give you an idea.
   
Comments
   
Sorry, this is quite irrelevant to threads. Even though it can help with understanding of by ref, OP probably already understand it.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Cookies | Terms of Service
Web06 | 2.8.190306.1 | Last Updated 4 May 2011
Copyright © CodeProject, 1999-2019
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100