Delegates: how to pass them?  
Author Message
Alexey Raga





PostPosted: .NET Base Class Library, Delegates: how to pass them? Top

Hello,

I want to create an object which can be parametrized by any function, and can run this function in another thread, like:

AsyncCalculation<int> = new AsyncCalculation<int>( ..here is a function ..);

I cannot use specific delegate because it is up do developer to decide which function with which parameters he/she wants to use.
So I decided to use my own invoker which can return a result.

Here is a code:

public delegate T Invoker<T>();
static
void Main(string[] args)
{
   
List<Invoker<int>> list = new List<Invoker<int>>();

   
for (int j = 0; j < 10; j++)
    {
       
Invoker<int>inv2 = new Invoker<int>(
       
delegate()
        {
           
Thread.Sleep(100); //do something in the thread
           
Console.WriteLine(j);
            return j;
        });

       
//here I want to pass my inv2 variable as a parameter 
       
//into another function to run it in another thread,
       
//but just store it in the collection
       
list.Add(inv2);
    }

    foreach (Invoker<int> inv in list)
        inv();

    Console.ReadKey();
}

As you see, I want to have a list of Invokers  to start them later in different threads.

But the output of this program is:

10
10
10
10
......

As I understand, it is because my anonymous delegate is compiled as a class, and the variable "j" becomes a field of this class. And all the Invokers have the reference to the same instance of  this class.

So, my question is:
 - Is it possible to have MethodInvokers with different instances in them How to create these instances if I only have delegates

 - Could you offer another solution of my problem




.NET Development22  
 
 
Brendan Grant





PostPosted: .NET Base Class Library, Delegates: how to pass them? Top

When you create your delegate instances you are in effect creating mini methods based on the code within, but also code that can reference the code around where it was created.

While the scope of the variable j ordinarily would end at the end of the for loop, each of your created delegates is referencing the same number and help to keep it alive a tad bit longer.

But why 10 That’s the value that causes the loop to end even though it does not ever run through it with j = 10.

Instead of trying to manually set values in the delegate at creation time you’ve got two options, either set those values at compile time, or modify your delegate and pass the needed values in ala:

public delegate T Invoker<T>(T t);

static void Main(string[] args)

{

List<Invoker<int>> list = new List<Invoker<int>>();

for (int j = 0; j < 10; j++)

{

Invoker<int> inv2 = delegate(int k)

{

Thread.Sleep(100);

Console.WriteLine(k);

return k;

};

list.Add(inv2);

}

for (int x = 0; x < list.Count; x++)

{

//On the delegate that is located at index x, call it and pass in the value x

list[x](x);

}

Console.ReadKey();

}

Does this sort of change fit your needs