views:

132

answers:

5

Hi. Let's say I have a function

public void SendMessage(Message message)
{
   // perform send message action
}

Can I create a delegate for this kind of function? If so, how can I pass a message when I use the delegate?

In my case, the function is used by Thread. Whenever there is an event, I need to send a message to the server, to keep the record. I also need to keep it running in background, so that it won't affect the application. However, the threading needs to use delegate

Thread t = new Thread(new ThreadStart(SendMessage));

and I don't know how to pass the message into the delegate. Thanks.

+11  A: 

Sure

public delegate void DelWithSingleParameter(Message m);

Passing a message can be done with the following

DelWithSingleParameter d1 = new DelWithSingleParameter(this.SomeMethod);
d1(new Message());

Also as @Mehrdad pointed out in newer versions of the framework you no longer need to define such delegates. Instead reuse the existing Action<T> delegate for this type of operation.

Action<Message> d1 = new Action<Message>(this.SomeMethod);
d1(new Message());
JaredPar
or simply `Action<Message>` ;)
Mehrdad Afshari
1+. In newer versions of the language you can omit the "new Action<>" as well, as you surely know ;)
Skurmedel
@Skurmedel or I could go the other way and use `var` instead of an explicit variable type ;)
JaredPar
Interestingly, `Action<T>` (with a single type param) has been around forever now (since .NET 2.0) and is declared in `mscorlib.dll` but the other variants (including the non-generic one) are side effects of LINQ and came in 3.5; they are declared in `System.Core.dll`.
Mehrdad Afshari
@Mehrdad this changes in .Net 4.0. Now all of them reside in mscorlib and they are type forwarded from System.Core.dll. Except for Silverlight where they are still in System.Core
JaredPar
I prefer to create a new delegate with a direct assignment of the method. It's just a little syntactic sugar, but I think it makes the intention more clear: `DelWithSingleParameter d1 = this.SomeMethod;`
Matt Greer
@Jared: Isn't Silverlight 4 supposed to be compatible with .NET 4.0 in core assemblies?
Mehrdad Afshari
@Mehrdad, yes AFAIK. It is compatible in the sense that from a compile stand point the difference doesn't matter due to the type forwarder. But yes there is a functional difference if you depend on the assembly where these values live. This is a bad choice though given that we've already moved Func from System.Core -> mscorlib
JaredPar
+3  A: 

sure, just define the delegate that way:

 delegate void SendMessageDelegate(Message message);

Then just invoke it as normal:

 public void InvokeDelegate(SendMessageDelegate del) 
 {
      del(new Message());
 }
Matt Greer
+1  A: 

Sure, see here for an example.

Ariel
+2  A: 

You need to use a ParametizedThreadStart. See here:

http://msdn.microsoft.com/en-us/library/system.threading.parameterizedthreadstart.aspx

TJMonk15
That is a specialized delegate used by the threading infrastructure. Using it outside of that context doesn't make much sense. He is better off creating his own delegate, or as Mehrdad said above, use `Action<T>`.
Matt Greer
Look at his question again. He specifically says this question is in refernce to passing a parameter to a Thread to be run in the background :-P
TJMonk15
Ah yes, you are correct. Sorry about that, it's too late to take back my downvote. You have the best answer of all here.
Matt Greer
Its cool :) I can't remember how many times i've misread a question.
TJMonk15
A: 

You can also do thing like that

object whatYouNeedToPass = new object();

Thread t = new Thread( () => 
{
    // whatYouNeedToPass is still here, you can do what ever you want :)
});

t.Start();
hoodoos