hs2d
hs2d

Reputation: 6189

C# running InvokeMember in thread

so what i am tryng to do is to run the InvokeMember in a thread. Got the info here how to do it: C# : Invoke a method with [Type].InvokeMember() in a separate Thread

So my code looks like this right now and this works:

            Assembly OCA = Assembly.LoadFrom("./CardMax2.Elkart.OrderClutchAgent.dll");
            Type[] types = OCA.GetTypes();
            foreach (var type in types)
            {
                //MethodInfo[] methods = type.GetMethods();
                if (type.Name == "OrderClutchAgent")
                {
                    var obj = Activator.CreateInstance(type);
                    type.InvokeMember("RunAgent",BindingFlags.Default | BindingFlags.InvokeMethod,null,obj,null);
                }

            }

Now when i try to run it in a thread, the code looks like this:

            Assembly OCA = Assembly.LoadFrom("./CardMax2.Elkart.OrderClutchAgent.dll");
            Type[] types = OCA.GetTypes();
            foreach (var type in types)
            {
                //MethodInfo[] methods = type.GetMethods();
                if (type.Name == "OrderClutchAgent")
                {
                    var obj = Activator.CreateInstance(type);
                    Thread t = new Thread(delegate()
                                              {
                                                  type.InvokeMember("RunAgent", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null);
                                              });
                    t.Start();
                }

            }

But with this code i am getting strange exception:

Method 'Org.BouncyCastle.Asn1.X509.TbsCertificateList+RevokedCertificatesEnumeration+RevokedCertificatesEnumerator.RunAgent' not found.

Am i doing something totally wrong or maybe someone can point out why i am getting this exception..

Upvotes: 2

Views: 1092

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062512

the legendary foreach capture issue - by the time it gets around to invoking it (on a different thread), the type variable refers to a different Type...

Make a copy instead:

foreach (var tmp in types)
{
    var type = tmp;
    // your code
}

The difference is that the loop variable (type in your example, tmp in mine) is scoped outside the loop (according to the spec), hence for capture purposes it is a single variable common to the entire loop. However, type in my example is scoped inside the loop, so (for capture purposes) is treated as a different variable per iteration.

Upvotes: 3

Related Questions