Mam funkcję, która wywołuje żądanie odczytu lub zapisu na porcie szeregowym, a następnie zwraca wartość, która została odczytana. Używam programu Commstudio Express (implementuję klasę z Commstudio), ale funkcje czasu oczekiwania w ogóle nie działają, więc próbuję wprowadzić własny limit czasu. Obecnie mam timer ustawiony na żądanie odczytu lub zapisu do portu, a jeśli timer się wyłączy, oddzwanianie zamyka połączenie powodując wyjątek. Próbowałem, aby wywołanie zwrotne zegara rzuciło wyjątek, ale wyjątek musi zostać rozpropagowany przez wątek, który wywoływał oryginalną funkcję odczytu/zapisu, więc w ten sposób działa, ale mam wrażenie, że jest niechlujny i musi być lepszym sposobem robienia tego, co chcę.Implementacja limitu czasu na funkcji zwracającej wartość
Odpowiedz
Oto ogólnym rozwiązanie pozwala owinąć dowolną metodą timeout:
http://kossovsky.net/index.php/2009/07/csharp-how-to-limit-method-execution-time/
wykorzystuje użyteczne Thread.Join przeciążenia, który akceptuje limitu czasu w milisekundach, a nie ręcznie, za pomocą liczników. Jedyną rzeczą, którą chciałbym zrobić inaczej jest zamiana flagi sukces i wartość wynik dopasować wzór TryParse, co następuje:
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;
}
I to jak byś go używać:
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");
Można też dodaj przeciążenia, które akceptują Action zamiast Func, jeśli chcesz wykonać metodę, która nie zwraca wartości.
Co z tym http://stackoverflow.com/a/990566/206730? Więcej w http://stackoverflow.com/questions/299198/implement-c-sharp-generic-timeout – Kiquenet
** Ważne: ** przed 'thread.Start()', powinieneś ustawić 'thread.IsBackground = true' inaczej wątek nadal działa po przekroczeniu limitu czasu, a po zamknięciu aplikacji pozostanie uruchomiony w Menedżerze zadań. –
@ user2270404 Wątek jest przerywany po dwóch wierszach kodu po jego uruchomieniu. O ile wątek nie chwyta wyjątku ThreadAbortException i wywołuje "ResetAbort" lub coś wyrzuca wyjątek, nie widzę sposobu, w jaki wątek mógłby nadal działać. To powiedziawszy, wywołanie 'Join' z limitem czasu mniejszym niż -1 ** spowoduje ** [zgłoszenie wyjątku] (http://msdn.microsoft.com/en-us/library/6b1kkss0.aspx), więc ktokolwiek skopiowanie tego kodu powinno sprawdzić poprawność danych wejściowych (a jeśli to nie wystarczy, to ustaw również "IsBackground"). –
Wygląda na to, że robisz blokujący odczyt/zapis. To, co chcesz zrobić, to nie blokować odczytu/zapisu.
Prawdopodobnie jest sposób, aby powiedzieć, że port COM nie jest blokowany.
Czy jesteś pewien, że limity czasu nie działają z commstudio? może musisz zrobić coś specjalnego, aby je zainicjować.
W każdym przypadku chcesz przeczytać jak najwięcej danych i jeśli nie ma czasu na wyjście (w zależności od wartości limitu czasu). Będziesz chciał zachować pętlę, gdy żadne dane nie będą dostępne i nie będzie błędu, a następnie zwróci warunek czasu, jeśli nie było nic dostępnego.
Spraw, aby funkcja odczytu zwracała liczbę całkowitą. wartości ujemne = wartość błędu np. -1 = timeout, dodatnia liczba bajtów przeczytanych ... przynajmniej tak bym to zrobił.
Jestem prawie pewien, że limit czasu nie działa, zdarzenie DeviceError nigdy nie jest wywoływane i nic się nie dzieje, nawet pozostawiając to na godzinę. Moja funkcja odczytu jest prostym przeciążeniem, które dodaje pewne niestandardowe logowanie, ale ostatecznie jest to baza.Read(). – MGSoto
Dla porównania możesz po prostu przetestować, czy jest coś dostępnego, a następnie zrobić odczyt zamiast robić blokowanie odczytu, nie wiedząc, że jest jeszcze coś. Coś takiego:
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--;
}
Jeśli ktoś chce to zrobić w VB.Net, nie słuchaj tych, którzy twierdzą, że nie można tego zrobić! Może zajść konieczność zmiany parametrów ogólnych w celu dopasowania do przypadku użycia.
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
a przykładem na to, jak go używać (mój był z Regex.Match
, które czasami udaje się do nigdy nie wylądować jeśli struktura zawiera zbyt wiele dzikich kart:
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. Domyślna wartość limitu czasu na selenowym webdriverze
- 2. RestTemplate - domyślna wartość limitu czasu
- 3. jak zmniejszyć wartość limitu czasu połączenia ssh
- 4. feedparser z limitu czasu
- 5. Ustawianie limitu czasu na funkcję recv
- 6. Ustawienia limitu czasu HttpURLConnection
- 7. Pozostało czasu na sesję do czasu przekroczenia limitu czasu
- 8. HippoMocks - kpiąc z funkcji zwracającej unique_ptr
- 9. Ustawianie limitu czasu limitu czasu oczekiwania w joomla
- 10. Różnice w formach dopuszczonego limitu czasu sesji i limitu czasu
- 11. Ustawienie limitu czasu transakcji JBoss?
- 12. Wydłużenie limitu czasu odpytywania
- 13. Zmiana limitu czasu SqlConnection
- 14. Dostosowywanie limitu czasu sesji na użytkownika - ASP.NET
- 15. Ustawianie limitu czasu na wywołanie urllib2.request()
- 16. Ustawianie limitu czasu rozmów CDI na świecie
- 17. Najlepszy sposób na pokonanie limitu czasu WCF
- 18. Wykrywanie limitu czasu w ffmpeg
- 19. Planowanie limitu czasu w Haskell
- 20. Jak ustawić wartość limitu czasu połączenia dla pgAdmin?
- 21. Jak uzyskać fopen do limitu czasu właściwie
- 22. Konfigurowanie limitu czasu pulsu, interwału pulsu i zamykania limitu czasu na serwerze
- 23. Java, zwiększenie limitu czasu gniazda
- 24. Zwiększenie błędu 504 limitu czasu
- 25. Geopy: błąd przekroczenia limitu czasu
- 26. Metoda limitu czasu w java
- 27. Monitorowanie synchronicznej metody limitu czasu
- 28. Błąd limitu czasu dla Androida
- 29. Zwiększenie limitu czasu dla .ashx
- 30. Wdrażanie limitu czasu w C#
Podobny w http: // przepełnienie stosu.com/questions/299198/implement-c-sharp-generic-timeout – Kiquenet