J'ai une fonction qui appelle une demande de lecture ou d'écriture sur un port série, puis renvoie la valeur lue. J'utilise CommStudio Express (je suis en train de mettre en œuvre une classe de Postudio), mais les fonctionnalités du délai d'attente ne semblent pas travailler du tout, alors j'essaie de mettre en œuvre mon propre délai d'attente. Actuellement, j'ai une minuterie qui est définie sur demande de lire ou d'écrire sur le port, et si la minuterie s'éteint, le rappel ferme la connexion qui provoque une exception. J'ai essayé d'avoir le rappel de la minuterie jeter une exception, mais l'exception doit être propagée à travers le fil qui appelait la fonction de lecture / écriture originale, de cette manière, cela fonctionne, mais je me sens comme désordonné et là doit être une meilleure façon de faire ce que je veux. p>
4 Réponses :
On dirait que vous faites un blocage de lecture / écriture. Ce que vous voulez faire est une lecture / écriture non bloquante. P>
Il y a probablement un moyen de dire au port COM que vous souhaitez non-bloquer. P>
Êtes-vous sûr que les délais d'expiration ne fonctionnent pas avec Postudio? Peut-être que vous devez faire quelque chose de spécial pour les initialiser. P>
Dans tous les cas, vous souhaitez lire autant de données que possible et si aucun n'est disponible (en fonction de la valeur de l'heure terminée). Vous voudrez continuer à bouffer pendant aucune donnée disponible et sans erreur, puis retourne une condition de temps externe s'il n'y avait rien de disponible. P>
Faites de votre fonction de lecture renvoie un entier. valeurs négatives = valeur d'erreur par ex. -1 = Timeout, nombre positif d'octets lisent ... au moins c'est la façon dont je le ferais. P>
Je suis à peu près sûr que le délai d'attente ne fonctionne pas, l'événement des appareilsError n'est jamais soulevé et que rien ne se passe même de la laisser courir pendant une heure. Ma fonction de lecture est une surcharge simple qui ajoute une journalisation personnalisée, mais à la fin, c'est une base.Lead ().
Voici une solution générique qui vous permet d'envelopper n'importe quelle méthode dans un délai d'attente:
http://kossovsky.net/index.php/2009/07/cshaparp-how-to-limit-method-execution-time/
Il utilise l'utile thread.join surcharge Cela accepte un délai d'attente en millisecondes plutôt que manuellement à l'aide de la minuterie. La seule chose que je ferais différemment est d'échanger le drapeau de réussite et de la valeur de résultat pour correspondre au Tryparse motif, comme suit: p> Et c'est ainsi que vous l'utiliseriez: P> var func = new Func<string>(() =>
{
Thread.Sleep(200);
return "success";
});
string result;
Debug.Assert(!TryExecute(func, 100, out result));
Debug.Assert(result == null);
Debug.Assert(TryExecute(func, 300, out result));
Debug.Assert(result == "success");
Qu'en est-il de cette Stackoverflow.com/a/990566/206730 ? Plus dans Stackoverflow.com/questions/299198/.../ a>
IMPORTANT: B> avant thread.start () code>, vous devez définir
thread.isbackground = true code> sinon le thread ne fonctionne pas après le délai d'attente et après la fermeture du Application, il restera en cours d'exécution dans le gestionnaire de tâches.
@ user2270404 Le thread se fait avorter deux lignes de code après son démarrage. Sauf si le fil n'atteint le threadabortexception et les appels resetAbort code> ou quelque chose jette une exception, je ne vois pas comment le fil pouvait continuer à courir. Cela dit, appelant
rejoindre code> avec un délai d'attente inférieur à -1 sera b>
isbackground code> aussi).
Pour le comport, vous pouvez simplement tester s'il y a quelque chose de disponible et ensuite faire une lecture au lieu de faire une lecture de blocage sans savoir qu'il y a encore quelque chose. Quelque chose comme:
Au cas où quelqu'un veut faire cela dans vb.net, n'écoutez pas ceux qui disent que cela ne peut pas être fait! Vous devrez peut-être modifier vos paramètres génériques en fonction de votre cas d'utilisation.
Public Function Match(Input As String) As Match If Regex Is Nothing Then Return Nothing Dim RegexMatch As System.Text.RegularExpressions.Match = Nothing Dim Func As New Func(Of String, System.Text.RegularExpressions.Match)(Function(x As String) Regex.Match(x)) If Runtime.TryExecute(Of String, System.Text.RegularExpressions.Match)(Func, Input, 2000, RegexMatch) Then Return (New Match(Me, Regex.Match(Input), Input)) Else Return Nothing End If End Function
Similaire dans Stackoverflow.com/questions/299198/.../ a>