Casting TResult in TaskTResult zu System.Object

8

Ich lade eine Assembly und rufe eine statische Methode auf, die ein neues Objekt vom Typ "MyClass1" (dieser Typ wird zur Laufzeit angegeben) durch Reflektion mit MethodInfo.Invoke () erzeugt. Dies funktioniert, wenn es sich bei der Methode um eine normale Synchronisierungsmethode handelt. Die aufgerufene Methode ist jedoch eine asynchrone Methode, die Task & lt; MyClass1 & gt; zurückgibt, die verwendet wird, um das Ergebnis unter Verwendung von task.Result abzurufen.

Idealerweise sollte ich MyClass1 als TResult in der Aufgabe verwenden, aber der Typ wird nur zur Laufzeit bestimmt, also kann ich das nicht tun. Ich suche nach einem Weg, um die Aufgabe und das Ergebnis zu bekommen. Ich versuche, das TResult an System.Object zu übergeben und die Klasse als generisches Objekt abzurufen. Das Folgende ist der Code, den ich für diesen Zweck verwende.

%Vor%

Nachfolgend wird die Methode (Testcode) durch Reflektion aufgerufen. Das

%Vor%

Leider verursacht das Umwandeln von TResult System.InvalidCastException.

%Vor%

Wie kann ich das TResult in Task & lt; & gt; zu einem generischen Objekt und das Ergebnis mit task.Result erhalten? Ich würde jede Hilfe bei der Lösung dieses Problems zu schätzen wissen.

    
mtcup 16.02.2014, 00:16
quelle

3 Antworten

16
___ qstntxt ___

Ich lade eine Assembly und rufe eine statische Methode auf, die ein neues Objekt vom Typ "MyClass1" (dieser Typ wird zur Laufzeit angegeben) durch Reflektion mit MethodInfo.Invoke () erzeugt. Dies funktioniert, wenn es sich bei der Methode um eine normale Synchronisierungsmethode handelt. Die aufgerufene Methode ist jedoch eine asynchrone Methode, die Task & lt; MyClass1 & gt; zurückgibt, die verwendet wird, um das Ergebnis unter Verwendung von task.Result abzurufen.

Idealerweise sollte ich MyClass1 als TResult in der Aufgabe verwenden, aber der Typ wird nur zur Laufzeit bestimmt, also kann ich das nicht tun. Ich suche nach einem Weg, um die Aufgabe und das Ergebnis zu bekommen. Ich versuche, das TResult an System.Object zu übergeben und die Klasse als generisches Objekt abzurufen. Das Folgende ist der Code, den ich für diesen Zweck verwende.

%Vor%

Nachfolgend wird die Methode (Testcode) durch Reflektion aufgerufen. Das

%Vor%

Leider verursacht das Umwandeln von TResult System.InvalidCastException.

%Vor%

Wie kann ich das TResult in Task & lt; & gt; zu einem generischen Objekt und das Ergebnis mit task.Result erhalten? Ich würde jede Hilfe bei der Lösung dieses Problems zu schätzen wissen.

    
___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ tag123asynchronous ___ Asynchrones Programmieren ist eine Strategie zum Verzögern von Operationen mit hoher Latenz oder niedriger Priorität, üblicherweise um die Leistung, Reaktionsfähigkeit und / oder die Kompostierbarkeit von Software zu verbessern. Solche Strategien werden normalerweise unter Verwendung einer Kombination von ereignisgesteuerter Programmierung und Rückrufen verwendet und verwenden optional die Nebenläufigkeit durch Koroutinen und / oder Threads. ___ answer21800002 ___

Sie können Task<T> nicht auf Task<object> anwenden, weil Task<T> nicht kovariant (es ist auch nicht kontravariant). Die einfachste Lösung wäre, etwas mehr Reflexion zu verwenden:

%Vor%

Dies ist langsam und ineffizient, aber verwendbar, wenn dieser Code nicht oft ausgeführt wird. Nebenbei: Was nutzt eine asynchrone Methode MakeMyClass1 , wenn Sie das Warten auf das Ergebnis blockieren wollen?

    
___ answer30857843 ___

Eine andere Möglichkeit besteht darin, zu diesem Zweck eine Erweiterungsmethode zu schreiben:

%Vor%

Es ist keine blockierende Lösung und behält den ursprünglichen Zustand / die Ausnahme der Aufgabe bei.

    
___ answer29103765 ​​___

Als Erweiterung der akzeptierten Antwort können Sie die Blockierung vermeiden, indem Sie %code% dazwischen warten:

%Vor%

Natürlich ist dies nur dann richtig asynchron, wenn alle Methoden in der Aufrufliste als %code% markiert sind und Sie %code% anstelle von %code% überall verwenden.

    
___ tag123task ___ Eine Aufgabe ist eine Abstraktion, die verwendet wird, um mit Nebenläufigkeit zu arbeiten, sie kann eine Operation bezeichnen, die gleichzeitig mit dem Rest eines Programms ausgeführt werden sollte. Eine Aufgabe ist ein gleichzeitiger Ausführungsthread in Ada und stellt eine asynchrone Operation in .NET dar. Sie entspricht auch Threads in Java. ___ qstnhdr ___ Casting TResult in TaskTResult zu System.Object ___
Anton Tykhyy 16.02.2014, 01:13
quelle
7

Eine andere Möglichkeit besteht darin, zu diesem Zweck eine Erweiterungsmethode zu schreiben:

%Vor%

Es ist keine blockierende Lösung und behält den ursprünglichen Zustand / die Ausnahme der Aufgabe bei.

    
David Desmaisons 16.06.2015 02:24
quelle
5
___ qstntxt ___

Ich lade eine Assembly und rufe eine statische Methode auf, die ein neues Objekt vom Typ "MyClass1" (dieser Typ wird zur Laufzeit angegeben) durch Reflektion mit MethodInfo.Invoke () erzeugt. Dies funktioniert, wenn es sich bei der Methode um eine normale Synchronisierungsmethode handelt. Die aufgerufene Methode ist jedoch eine asynchrone Methode, die Task & lt; MyClass1 & gt; zurückgibt, die verwendet wird, um das Ergebnis unter Verwendung von task.Result abzurufen.

Idealerweise sollte ich MyClass1 als TResult in der Aufgabe verwenden, aber der Typ wird nur zur Laufzeit bestimmt, also kann ich das nicht tun. Ich suche nach einem Weg, um die Aufgabe und das Ergebnis zu bekommen. Ich versuche, das TResult an System.Object zu übergeben und die Klasse als generisches Objekt abzurufen. Das Folgende ist der Code, den ich für diesen Zweck verwende.

%Vor%

Nachfolgend wird die Methode (Testcode) durch Reflektion aufgerufen. Das

%Vor%

Leider verursacht das Umwandeln von TResult System.InvalidCastException.

%Vor%

Wie kann ich das TResult in Task & lt; & gt; zu einem generischen Objekt und das Ergebnis mit task.Result erhalten? Ich würde jede Hilfe bei der Lösung dieses Problems zu schätzen wissen.

    
___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ tag123asynchronous ___ Asynchrones Programmieren ist eine Strategie zum Verzögern von Operationen mit hoher Latenz oder niedriger Priorität, üblicherweise um die Leistung, Reaktionsfähigkeit und / oder die Kompostierbarkeit von Software zu verbessern. Solche Strategien werden normalerweise unter Verwendung einer Kombination von ereignisgesteuerter Programmierung und Rückrufen verwendet und verwenden optional die Nebenläufigkeit durch Koroutinen und / oder Threads. ___ answer21800002 ___

Sie können Task nicht auf async anwenden, weil await nicht kovariant (es ist auch nicht kontravariant). Die einfachste Lösung wäre, etwas mehr Reflexion zu verwenden:

%Vor%

Dies ist langsam und ineffizient, aber verwendbar, wenn dieser Code nicht oft ausgeführt wird. Nebenbei: Was nutzt eine asynchrone Methode .Result , wenn Sie das Warten auf das Ergebnis blockieren wollen?

    
___ answer30857843 ___

Eine andere Möglichkeit besteht darin, zu diesem Zweck eine Erweiterungsmethode zu schreiben:

%Vor%

Es ist keine blockierende Lösung und behält den ursprünglichen Zustand / die Ausnahme der Aufgabe bei.

    
___ answer29103765 ​​___

Als Erweiterung der akzeptierten Antwort können Sie die Blockierung vermeiden, indem Sie %code% dazwischen warten:

%Vor%

Natürlich ist dies nur dann richtig asynchron, wenn alle Methoden in der Aufrufliste als %code% markiert sind und Sie %code% anstelle von %code% überall verwenden.

    
___ tag123task ___ Eine Aufgabe ist eine Abstraktion, die verwendet wird, um mit Nebenläufigkeit zu arbeiten, sie kann eine Operation bezeichnen, die gleichzeitig mit dem Rest eines Programms ausgeführt werden sollte. Eine Aufgabe ist ein gleichzeitiger Ausführungsthread in Ada und stellt eine asynchrone Operation in .NET dar. Sie entspricht auch Threads in Java. ___ qstnhdr ___ Casting TResult in TaskTResult zu System.Object ___
Todd Menier 17.03.2015 15:53
quelle

Tags und Links