Je rencontre des problèmes lors de l'utilisation d'un rappel dans un projet WCF.Vérification que tous les rappels ont été terminés avant d'envoyer une nouvelle requête via un canal Duplex utilisant WCF
D'abord, le serveur invoque une fonction Foo
sur le client qui transmet ensuite la demande à une interface graphique Windows Forms:
GUI CLASSE
delegate void DoForward();
public void ForwardToGui() {
if (this.cmdSomeButton.InvokeRequired) {
DoForward d = new DoForward(ForwardToGui);
this.Invoke(d);
}
else {
Process(); // sets result variable in callback class as soon as done
}
}
}
CALLBACK CLASSE
object _m = new object();
private int _result;
public int result {
get { return _result; }
set {
_result = value;
lock(_m) {
Monitor.PulseAll(_m);
}
}
}
[OperationContract]
public int Foo() {
result = 0;
Program.Gui.ForwardToGui();
lock(_m) {
Monitor.Wait(_m, 30000);
}
return result;
}
Le problème maintenant est que l'utilisateur devrait être en mesure d'annuler le processus, ce qui ne fonctionne pas correctement:
SERVEUR INTERFACE
[OperationContract]
void Cleanup();
GUI CLASSE
private void Gui_FormClosed(object sender, EventArgs e) {
Program.callbackclass.nextAction = -1;
// so that the monitor pulses and Foo() returns
Program.server.Cleanup();
}
Le problème est que Cleanup()
se bloque. Toutefois, lorsque je ferme le formulaire lorsque Process()
ne fonctionne pas, cela fonctionne correctement.
La source semble être que le Cleanup()
est appelé avant les impulsions du moniteur etc. et donc une nouvelle requête est envoyée au serveur avant que la dernière requête du serveur n'ait pas encore été répondue.
Comment puis-je résoudre ce problème? Comment puis-je m'assurer avant d'appeler le Cleanup()
qu'aucun Foo()
n'est en cours d'exécution?
Je suis devenu trop confus en essayant d'assembler les bribes de code ensemble. Les deux extraits de code intitulés "Classe GUI" dans la même classe GUI? Le premier avertissement que je vois est que vous appelez System.Windows.Form.Invoke au lieu de System.Windows.Forms.BeginInvoke. Est-ce intentionnel? –
Les deux parties étiquetées avec la classe GUI sont de la même classe. J'essaie maintenant. Il semble que BeginInvoke a fait le travail! Merci :-) Pourriez-vous poster votre commentaire à nouveau comme une réponse? – Etan