Ho una funzione che richiama una richiesta di lettura o scrittura su una porta seriale e quindi restituisce il valore letto. Sto usando Commstudio Express (sto implementando una classe da Commstudio), ma le funzionalità di timeout non sembrano funzionare affatto, quindi sto cercando di implementare il mio timeout. Attualmente ho un timer che viene impostato su richiesta per leggere o scrivere sulla porta, e se il timer si spegne, il callback chiude la connessione causando un'eccezione. Ho cercato di fare in modo che la richiamata del timer generasse un'eccezione, ma l'eccezione deve essere propagata attraverso il thread che stava chiamando la funzione originale di lettura/scrittura, quindi in questo modo funziona, ma mi sembra che sia disordinato e deve essere un modo migliore per fare ciò che voglio.Implementazione di un timeout su una funzione che restituisce un valore
risposta
Ecco una soluzione generica che permette di avvolgere qualsiasi metodo in un timeout:
http://kossovsky.net/index.php/2009/07/csharp-how-to-limit-method-execution-time/
Esso utilizza l'utile Thread.Join overload che accetta un timeout in millisecondi piuttosto che manualmente utilizzando i timer. L'unica cosa che vorrei fare in modo diverso è di swap la bandiera successo e il valore del risultato per abbinare il modello TryParse, come segue:
public static T Execute<T>(Func<T> func, int timeout)
{
T result;
TryExecute(func, timeout, out result);
return result;
}
public static bool TryExecute<T>(Func<T> func, int timeout, out T result)
{
var t = default(T);
var thread = new Thread(() => t = func());
thread.Start();
var completed = thread.Join(timeout);
if (!completed) thread.Abort();
result = t;
return completed;
}
Ed è così che si dovrebbe utilizzare:
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");
Si potrebbe anche aggiungere sovraccarichi che accettano Action anziché Func se si desidera eseguire un metodo che non restituisce un valore.
Che dire di questo http://stackoverflow.com/a/990566/206730? Altro in http://stackoverflow.com/questions/299198/implement-c-sharp-generic-timeout – Kiquenet
** Importante: ** prima di 'thread.Start()', si dovrebbe impostare 'thread.IsBackground = true' altrimenti il thread continua a funzionare dopo il timeout e, dopo aver chiuso l'applicazione, rimarrà in esecuzione in Task Manager. –
@ user2270404 Il thread ottiene due righe di codice interrotte dopo l'avvio. A meno che il thread non rilevi l'eccezione ThreadAbortException e invii "ResetAbort', o qualcosa generi un'eccezione, non vedo come il thread possa continuare a funzionare. Detto questo, chiamare 'Join' con un timeout inferiore a -1 ** farà ** [lanciare un'eccezione] (http://msdn.microsoft.com/en-us/library/6b1kkss0.aspx), quindi nessuno la copia di questo codice dovrebbe convalidare l'input (e se non sembra abbastanza impostato anche su 'IsBackground'). –
Sembra che tu stia eseguendo un blocco di lettura/scrittura. Quello che vuoi fare è una lettura/scrittura non bloccante.
Probabilmente esiste un modo per comunicare alla porta com che non si desidera bloccare.
Sei sicuro che i timeout non funzionano con commstudio? forse devi fare qualcosa di speciale per inizializzarli.
In ogni caso, si desidera leggere quanti più dati possibile e se nessuno è disponibile a scadenza (a seconda del valore del timeout). Avrai voglia di continuare il ciclo senza dati disponibili e nessun errore e quindi restituire una condizione di timeout se non c'era nulla disponibile.
Fare in modo che la funzione di lettura restituisca un numero intero. valori negativi = valore errore ad es. -1 = timeout, numero positivo di byte letti ... almeno questo è il modo in cui lo farei.
Sono abbastanza sicuro che il timeout non funzioni, l'evento DeviceError non viene mai generato e non accade nulla, lasciandolo funzionare per un'ora. La mia funzione di lettura è un semplice sovraccarico che aggiunge alcune registrazioni personalizzate, ma alla fine è una base. Leggi(). – MGSoto
Per il comport si potrebbe semplicemente verificare se c'è qualcosa disponibile e quindi fare una lettura invece di fare una lettura bloccata senza sapere che c'è ancora qualcosa. Qualcosa di simile:
Int32 timeout=1000;
String result = String.Empty';
while (timeout!=0) {
if (Serial.BytesToRead>0) {
while (Serial.BytesToRead>0) {
result+=Serial.ReadChar();
}
break;
}
Thread.Sleep(1);
timeout--;
}
Nel caso in cui qualcuno vuole fare questo in VB.Net, non ascoltare quelli che dicono che non si può fare! Potrebbe essere necessario modificare i parametri generici in base al proprio caso d'uso.
Public Shared Function Execute(Of I, R)(Func As Func(Of I, R), Input As I, TimeOut As Integer) As R
Dim Result As R
TryExecute(Func, Input, TimeOut, Result)
Return Result
End Function
Public Shared Function TryExecute(Of I, R)(Func As Func(Of I, R), Input As I, TimeOut As Integer, ByRef Result As R) As Boolean
Dim OutParam As R = Nothing
Dim Thread As New System.Threading.Thread(Sub() InlineAssignHelper(OutParam, Func(Input)))
Thread.IsBackground = True
Thread.Start()
Dim Completed As Boolean = Thread.Join(TimeOut)
If Not Completed Then Thread.Abort()
Result = OutParam
Return Completed
End Function
Private Shared Function InlineAssignHelper(Of T)(ByRef Target As T, ByVal Value As T) As T
Target = Value
Return Value
End Function
e un esempio di come usarlo (la mia era con Regex.Match
, che a volte si spegne in Never Never Land se i modelli contiene troppi jolly:
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
- 1. Posso scrivere un tipo di funzione che restituisce una funzione?
- 2. funzione che restituisce un valore dalla richiesta di chiamata ajax
- 3. Restituisce più di un valore da una funzione in Java
- 4. mappare un flusso con una funzione che restituisce un futuro
- 5. Una funzione che restituisce un set di dati
- 6. HippoMocks - mocking di una funzione che restituisce un unique_ptr
- 7. Nome di una funzione che restituisce un generatore
- 8. AlertDialog in una funzione che ha un valore di ritorno
- 9. funzione anonima non restituisce sempre un valore
- 10. Perché questa funzione Perl restituisce un valore?
- 11. Esiste una funzione che restituisce il valore ASCII di un carattere? (C++)
- 12. funzione R che restituisce una stringa letterale
- 13. In che modo una funzione restituisce in base al valore?
- 14. Macro in C per chiamare una funzione che restituisce un intero e quindi restituisce una stringa
- 15. funzione freccia ECMAScript6 che restituisce un oggetto
- 16. Funzione che restituisce un riferimento all'oggetto locale
- 17. Come scrivere un puntatore a una funzione che restituisce un puntatore a una funzione?
- 18. : quale denominazione di un metodo che restituisce un valore booleano?
- 19. Unità testare una funzione che restituisce un oggetto generatore
- 20. Come si dichiara una funzione che restituisce un puntatore a una funzione che restituisce un puntatore a funzione senza utilizzare un typedef in C?
- 21. Come scrivere un test di prova dell'unità per una funzione che restituisce un frame di dati
- 22. Come `({...})` restituisce un valore?
- 23. Sintassi per un puntatore a una funzione che restituisce un puntatore a funzione in C
- 24. Restituisce un array 2d da una funzione
- 25. funzione che restituisce una sintassi puntatore a funzione
- 26. Scrivere una funzione javascript al curry che può essere chiamata un numero arbitrario di volte che restituisce un valore sull'ultima chiamata di funzione
- 27. Perché questa funzione restituisce un valore diverso ogni volta?
- 28. Posso impostare un timeout per una funzione read() di InputStream?
- 29. stringa confronta in javascript che restituisce un valore booleano
- 30. Il valore entrySet() di una TreeMap restituisce un TreeSet
Simile a http: // StackOverflow.it/questions/299198/implement-c-sharp-generic-timeout – Kiquenet