Search code examples
c#wpfdynamicdllmessaging

WPF main app dynamically invoking a DLL...need messaging from the DLL prior to the return to the main app


I've done a lot of googling and searching here on stackoverflow but can't figure out how to get progress messages back from a dynamically called DLL prior to returning from the DLL. Let say the DLL is 10% finished...I want to show that progress. I'm used to just displaying what returns from a call but in this case I need the progress. Here is my code (C#, WPF project) to invoke the DLL. Just curious how to get messages back prior to the return...

string pathAndDLLFile = Path.GetFullPath(DLLName + ".DLL");
Assembly a = Assembly.LoadFile(pathAndDLLFile);
string typeField = DLLNamespace + "." + DLLClass;
Type myType = a.GetType(typeField);
MethodInfo testMethod = myType.GetMethod(DLLMethod);
object obj = Activator.CreateInstance(myType);
object c = testMethod.Invoke(obj, new Object[] { nodeChild });

Here is my DLL...

using System.Xml;

namespace InitialTest2
{
    public class Class1
    {
        public int test(XmlNode xmlTest)
        {
            int testCount = 0;
            int progress = 0;
            foreach (XmlAttribute attributeChild in xmlTest.Attributes)
            {
                if (attributeChild.Name != "name" && attributeChild.Name != "testNumber" && attributeChild.Name != "Estimate" && !attributeChild.Name.Contains("DLL"))
                {
                    if ((attributeChild.Name.Contains("MinLimit")) || (attributeChild.Name.Contains("MaxLimit")) || (attributeChild.Name.Contains("Unit")))
                    {
                        // not the attribute value
                    }
                    else
                    {
                        testCount ++;
                    }
                }
                progress = progress + 1;
                // ToDo: report progress back to the main ap

            }
            return testCount;

        }
        public int test3(XmlNode xmlTest)
        {
            return 3;
        }
    }
    public class Class2
    {
        public int test2(XmlNode xmlTest)
        {
            return 2;
        }
    }
}

Solution

  • This has nothing to do with dynamic invocation but the fact is that tour test method returns a single int value and nothing else.

    Such a method cannot report or return anything else than an int value back to the caller. How and where are you expect to get the current value of the local variable progress? You don't return anything from the method until after the foreach loop has been completed.

    If you want to return some kind of progress, or at least several values, from a synchronous method, you could change its return type to IEnumerable<int> and iterate over the return values, e.g.:

    public IEnumerable<int> test(XmlNode xmlTest)
    {
        int testCount = 0;
        int progress = 0;
        foreach (XmlAttribute attributeChild in xmlTest.Attributes)
        {
            if (attributeChild.Name != "name" && attributeChild.Name != "testNumber" && attributeChild.Name != "Estimate" && !attributeChild.Name.Contains("DLL"))
            {
                if ((attributeChild.Name.Contains("MinLimit")) || (attributeChild.Name.Contains("MaxLimit")) || (attributeChild.Name.Contains("Unit")))
                {
                    // not the attribute value
                }
                else
                {
                    testCount++;
                }
            }
            yield return progress + 1;
            // ToDo: report progress back to the main ap
    
        }
        yield return testCount;
    }
    

    Usage:

    IEnumerable<int> c = testMethod.Invoke(obj, new Object[] { nodeChild }) as IEnumerable<int>;
    if (c != null)
    {
        int count;
        foreach (var progress in c)
        {
            Console.WriteLine(progress);
            count = progress;
        }
        Console.WriteLine(count);
    }