2016-10-26 11 views
0

Ich habe eine DLL, die public Task<> Methode hat, die return Task.Factory.StartNew(() => ...) zurückgibt. Ich rufe es innerhalb eines Programms an und möchte, dass das Programm darauf wartet, dass die Ausführung der Aufgabe beendet wird, bevor es mit anderen Dingen fortfährt. Ich habe Thread.Sleep(6000) zu der DLL hinzugefügt, um längere Ausführung zu simulieren.C# warten DLL async Methode zu beenden

Wenn ich es wie dies

var invokedTask = myMethod.Invoke(Activator.CreateInstance(myClass), myParams); 

Aufruf Weiter geht es nur mit der Ausführung (wie erwartet). Aber dann habe ich das versucht:

var invokedTask = Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 
invokedTask.Wait(); 

Und es funktioniert nicht. Wie kann ich es von außerhalb der DLL warten lassen?

+0

In Ihrem zweiten Beispiel erstellen Sie eine * neue * 'Aufgabe'. Der einzige Job, den Sie dieser Aufgabe zuweisen, besteht darin, die Funktion "myMethod" auszuführen und die zurückgegebene Aufgabe zu ignorieren. Diese "Aufgabe" dauert natürlich nicht lange. Warum "wait" '' aufgerufeneTask' in deinem ersten Beispiel nicht? –

+0

Versuchte es bereits, aber 'aufgerufeneTask' ist nicht von' Task' Typ, sondern 'Objekt' – Norgul

+1

Aber es ist wirklich eine' Aufgabe'. Alles, was Sie brauchen, ist eine Besetzung - nicht meckern über das Erstellen von mehr Aufgaben. –

Antwort

1

Nur Wait für die Aufgabe, die zurückgegeben wird - nicht spin up andereTask nur die Original-Methode aufzurufen:

var invokedTask = (Task)myMethod.Invoke(Activator.CreateInstance(myClass), myParams); 
invokedTask.Wait(); 
0

Ich denke, die Rufmethode von der Asynchron-Schlüsselwort in der Definition haben muss.

async void (or Task) MyCaller() 
{ 
    await Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 

} 

nichtig oder Aufgabe hängt davon ab, welchen Kontext Sie sind in

0

Wenn Sie wait() ein Task.Factory.StartNew() das Ergebnis ist ein Task Daher müssen Sie wait() zwei Mal anrufen oder Sie können await Operator verwenden.

Daher können Sie Folgendes tun.

var invokedTask = Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 
var result=await await invokedTask; 

Oder Sie können wie folgt vorgehen

var invokedTask = Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 
invokedTask.Wait(); 
var resultTask=invokedTask.Result; 
resultTask.Wait(); 
var result=resultTask.Result; 

jedoch von der Frage, die Sie gebucht haben, es wie Ihr myMethod.Invoke() kehrt sieht Task.Factor.StartNew() deshalb würde Ich mag Sie

var result =await await myMethod.Invoke(Activator.CreateInstance(myClass), myParams); 

jedoch versuchen Es ist eine schlechte Übung, Wait() und dann Result() zu verwenden, da es den aktuellen Thread blockiert. Deshalb möchte ich Sie gerne benutzen erwarten.

0

Dieses Beispiel helfen können:

public class MagicClass 
{ 
    private int magicBaseValue; 

    public MagicClass() 
    { 
     magicBaseValue = 9; 
    } 

    public Task<int> ItsMagic(int preMagic) 
    { 
     return Task.Factory.StartNew(() => preMagic * magicBaseValue); 
    } 
} 

public class TestMethodInfo 
{ 
    public static void Main() 
    { 
     // Get the ItsMagic method and invoke with a parameter value of 100 
     Type magicType = typeof(MagicClass); 
     MethodInfo magicMethod = magicType.GetMethod("ItsMagic"); 
     var magicValue = ((Task<int>)(magicMethod.Invoke(Activator.CreateInstance(typeof(MagicClass)), new object[] { 100 }))).Result; 

     Console.WriteLine("MethodInfo.Invoke() Example\n"); 
     Console.WriteLine("MagicClass.ItsMagic() returned: {0}", magicValue.ToString()); 

     Console.ReadKey(); 
    } 
} 

Sie kann Ihre Invoke als Aufgabe <> und dann das Ergebnis abrufen. Dies wird warten, bis die Methode fertig ausgeführt ist.