J'essaie de vous connecter à mon serveur avec un Le scénario est comme suit: p> Que se passe-t-il ici est qu'un Donc, je n'ai aucune idée de ce qui se passe. Le problème est que je suis obligé d'attendre que l'application se ferme (comme si l'opération de connexion attend toujours un délai d'attente). Si un serveur est en ligne, il se connecte et se déconnecte simplement bien em>. p> Notes supplémentaires strong> ( demandé dans les commentaires em>): p> Voici le code pour créer le client (le client est une variable de membre: p> aussi la méthode de près : p> tcpclient.beginconnect / tcpclient.endconnect code> combo. Cependant, certaines choses ne fonctionnent pas comme elles le devraient.
tcpclient.beginconnect code> li>
client.close () code> est appelé dans le processus qui ferme la prise qui arrête à son tour l'opération ASYNC ) li>
tcpclient code> Connection Méthode de rappel strong> Donner
iAsyncResult code> li>
tcpclient.endconnect code> avec le
iAsynchresult donné code> li>
nullreferenceException code> se passe sur
endconnect code> (? strong>) li>
commence par code> est terminé (ce qui est étrange, car le rappel a déjà été appelé). li>
ul>
p>
NullReferenceException code> est capturé. Comme vous pouvez le voir sur la photo ci-dessus, ni
client code> ni
ar code> sont
null code>. Le problème est que le Documentation MSDN pour l'EndConnect < / a> ne mentionne pas le cas dans lequel cette exception est lancée. P>
NullReferenceException CODE>
Beginconnect code> Utilisation pour bloquer la fermeture de l'application au cas où la connexion ne peut pas être établie? P>
4 Réponses :
J'ai eu une erreur similaire et j'ai fini par utiliser ce code. Je ne sais pas si cela détiendra avec l'interface IAsyncResulte, mais il peut y avoir une manière similaire d'exécuter ce chèque. Je remarque que votre ar.asyncstate == null, alors essayez peut-être de commencer là-bas, c'est-à-dire qu'il est null lorsque vous vous connectez correctement?
private void OnConnect(IAsyncResult asyncResult) { if (OnConnectCompleted == null) return; // Check whether something is using this wrapper AsyncCompletedEventArgs args; try { Socket outSocket = (Socket) asyncResult.AsyncState; // Complete connection outSocket.EndConnect(asyncResult); args = new AsyncCompletedEventArgs(null); OnConnectCompleted(this, args); } catch (Exception e) { args = new AsyncCompletedEventArgs(e.Message); OnConnectCompleted(this, args); } }
Asyncstate est utilisé pour transmettre certaines données personnalisées à la méthode de rappel. Je n'ai pas de tel besoin, c'est pourquoi c'est null. Il ne peut pas produire d'erreur. Je ne comprends pas votre exemple (c'est incomplet). IAsynCreulsulte n'a aucune erreur et je suppose que vous devriez fournir le code de la méthode de Closocket () car c'est votre propre méthode personnalisée. Autrement, je ne sais pas comment votre exemple de code pourrait être utile.
CloseSocket () déclenche simplement quelques événements pour notifier toute autre partie du programme, puis exécute () sur la prise.
Le Si vous deviez suivre le EXEMPLE MSDN pour NullReferenceException code> est probablement dû à
tcpclient.client code> étant null.
tcpclient.beginconnect code> et transmettez le
tcpclient code> objet en tant que Objet d'état: p>
private void onConnEst(IAsyncResult ar)
{
try
{
TcpClient client = (TcpClient)ar.AsyncState;
if(client!=null && client.Client!=null)
{
client.EndConnect(ar);
}
}
catch(Exception ex){...}
}
Pourquoi moulez-vous AR.ASYNCRESUT? Vouliez-vous dire ar.asyncstate? Quoi qu'il en soit, mon client est un membre privé, donc je n'ai pas besoin de le transmettre à la méthode ASYNC. Je suis actuellement incapable (c'est-à-dire pas au travail) de vérifier si le TCPClient.client est NULL. Toutefois, sur la base de ma mémoire et de ma précédente expérience, si je n'appelle pas client.EndConnect, l'application est toujours suspendue lorsque j'essaie de le fermer. Il dure généralement la même chose que le délai de connexion (~ 20). Et si je ne ferme pas l'application lors de la tentative de connexion, le BEGINCONNECT échouera après la même période.
Oups - vous êtes correct, ar.asycrélu code> devrait être
ar.asyncstate code>. Post modifié pour refléter les changements.
Seriez-vous capable de publier la façon dont vous construisez le TCPCLIent et votre commenceur? Vous liez la prise avant de commencer? En outre, cela ne devrait pas y avoir d'importance, mais quel .NET Framework utilisez-vous?
J'ai mis à jour la question pour remplir les pièces manquantes. J'utilise .net 4.
Bien que je n'ai pas exécuté votre code exactement, Client.close () ne prend pas longtemps du tout. Je suggérerais de commenter les portions TCPClient de votre code (à des fins de test uniquement) et de voir si vous rencontrez toujours le retard. En dehors de cela, il pourrait y avoir quelque chose de poisson avec plusieurs threads verrouillant sur ConnectionAccess Code> Causant le délai, ce qui serait logique si vous n'avez pas connu le retard lors de la progression du code.
J'ai déjà essayé de faire exclure tout code TCPClient, puis cela fonctionne très bien. Comme je l'ai dit, le temps qu'il faut pour que l'application se ferme correspond au temps nécessaire au début de l'échec de la FinConnexion après qu'aucune connexion n'a été faite (délai d'attente). Par conséquent, je conclus que c'est que l'async commencent le fil qui reste actif. À propos de l'impasse, ce n'est pas le problème, car ce sont les deux seuls endroits que la serrure est obtenue et à partir de ce que vous pouvez voir, fermer (dans un bloc de capture) n'est pas enfermé dans ce verrou.
Ceci évidemment un bug à l'intérieur de la classe TCPClient. Je l'ai également fait face. Tcpclient.Dispose peut définir le champ client sur NULL, mais ne s'attend pas à cela. P>
Bienvenue pour! Vous voudrez peut-être envisager d'élaborer un peu plus sur les détails de l'insecte pour rendre votre réponse un peu plus complète pour les autres personnes qui peuvent venir sur cette question.
Est-ce que l'Infurexception donne-t-il plus d'informations sur ce qui était NULL?
@Tremmors Nope. InnerException est null. Aucune aide de la StackTrace aussi (OncpClientConnectionStablied> endconnect). :(
Oui, clairement un bug-cadre. Dans le cas où le Tcpclient est fermé avant que l'endconnexion () est appelé, il est censé lancer ObjectDisposedException. Je semble obtenir NullReferenceException à la place du premier ou deux fois, alors il commencera à lancer ObjectDisposedException comme prévu. Je vous suggère de manipuler simplement de la même chose que vous l'obtiendriez (c'est-à-dire que vous avez choisi / quelle que soit l'échec / quelle que soit autre raison que vous avez appelé étroite () »). Cependant, je ne sais pas si toutes les ressources risquent de fuir ici, car endconnect () ne complète pas. Probablement rien le GC ne peut pas gérer. :)
Comment cela n'a-t-il pas été corrigé dans .NET 4.8?