Category Archives: .NET

Cross-Thread invoke helper

Probabil cei care programeaza in .NET forms de ceva vreme se lovesc frecvent de problema invocarii unei metode a unui control, dintr-un thread altul decat cel care este owner-ul controlului. Nu intru in detaliile problemei, care coboara destul de jos la cozi de mesaje per thread, handle-uri windows si altele;

Solutia cel mai des intalnita este: se face un delegate cu semnatura metodei de invocat, se verifica daca este contextul threadului corect cu Control.IsInvokeRequired, si daca nu, atunci se apeleaza metoda prin Control.Invoke, cu delegate-ul definit anterior.

In timp devine “obositor” si mai ales la proiecte mari, definitia cate unui delegate pentru fiecare metoda posibila. O solutie la “oboseala” ar putea fi urmatoarea (mai putin cateva try – catch blocks 😉 :

class CrossThreadHelper
{
    private delegate Object CallMethodProxyDelegate(Control ctrl, String strMethod, object[] arguments);

    private static Object CallMethodProxy(Control ctrl, String strMethod, object[] arguments)
    {
        MethodInfo method;
        method = ctrl.GetType().GetMethod(strMethod);
        return method.Invoke(arguments);
    }

    public static Object CallMethod(Control ctrl, String strMethod, params object[] arguments)
    {
        if(ctrl.InvokeRequired)
        {
             Delegate = new CallMethodProxyDelegate(CallMethodProxy);
             Object[] newArgs = new Object[3];
             newArgs[0] = ctrl;
             newArgs[1] = strMethod;
             newArgs[2] = arguments;
             return ctrl.Invoke(del, newArgs);
         }

         return CallMethodProxy(ctrl, strMethod, arguments);
    }

}

Exemplu:

CrossThreadHelper.CallMethod(this.frmProgress, “Close”);