2010-05-02 4 views
2

J'essaye de faire des E/S asynchrones en utilisant BeginRead() dans JScript.NET, mais je n'arrive pas à faire fonctionner correctement la fonction de rappel.La génération de type délégué échoue dans JScript.NET

Voici le code:

function readFileAsync() { 
    var fs : FileStream = new FileStream('test.txt', FileMode.Open, FileAccess.Read); 
    var result : IAsyncResult = fs.BeginRead(new byte[8], 0, 8, readFileCallback), fs); 
    Thread.Sleep(Timeout.Infinite); 
} 

var readFileCallback = function(result : IAsyncResult) : void { 
print('ListenerCallback():'); 
} 

L'exception est un échec coulé:

Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'Microsoft.JScript.Closure' to type 'System.AsyncCallback'. 
at JScript 0.readFileAsync(Object this, VsaEngine vsa Engine) 
at JScript 0.Global Code() 
at JScript Main.Main(String[]) 

J'ai essayé de faire un casting explicite à la fois à AsyncCallback et à la base des types MulticastDelegate et délégué à pas profiter.

Les délégués sont censés être créés automatiquement, ce qui évite la nécessité de créer une nouvelle AsyncCallback explicitement, par exemple:

BeginRead(... new AsyncDelegate(readFileCallback), object); 

Et en fait, si vous essayez de créer le délégué du compilateur émet explicitement une erreur. Je dois manquer quelque chose ici.

Répondre

2

Le problème vient du fait que l'intérieur d'un délégué est créé en utilisant

Delegate.CreateDelegate(Type, Object, String) 

où type est le type de délégué pour créer, objet est l'instance sur laquelle la méthode sera appelée et chaîne est le nom de la méthode. Pour que cela fonctionne, la fonction doit être une méthode d'instance, nous devons donc définir une classe en tant que telle:

class AsyncFileReader 
{ 
    function readFileAsync() { 
     var fs : FileStream = new FileStream( 
      'test.txt', FileMode.Open, FileAccess.Read 
     ); 

     var result : IAsyncResult = fs.BeginRead( 
      new byte[8], 0, 8, ListenerCallback, fs 
     ); 
     // Sleep just for testing 
     Thread.Sleep(Timeout.Infinite); 
    } 

    function ListenerCallback(result : IAsyncResult) : void { 
     print('ListenerCallback():'); 
    } 

} // class 

Depuis le rappel peut désormais lié à une instance de AsyncFileReader lors de l'exécution, la conversion réussira. L'erreur listée ci-dessus était probablement l'une de mes tentatives de lancer explicitement, ce qui n'est pas ce qui se passe lors de la conversion ici.

Questions connexes