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;
}
}
}
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);
}