我有召唤出一个串口读取或写入请求,然后返回读取值的函数。 我使用Commstudio快递(我执行从Commstudio类),但它的超时功能的不会出现在所有的工作,所以我想实现我自己的超时。 目前,我有一个是根据要求设置为读取或写入到该端口的计时器,如果计时器熄灭,则回调关闭引起异常的连接。 我想有定时器的回调抛出一个异常,而是需要通过在呼唤着原来的读/写功能,所以这样一来,它的工作线程传播了异常,但我觉得这是凌乱而有必须有一个更好的方式做我想做的。
Answer 1:
这里是一个通用的解决方案,允许您将任何方法在超时:
http://kossovsky.net/index.php/2009/07/csharp-how-to-limit-method-execution-time/
它使用有用的Thread.join接受以毫秒为单位,而不是使用计时器手动过载。 我会做出不同的唯一事情是交换的成功标志和结果值匹配的TryParse模式,如下所示:
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;
}
这是你将如何使用它:
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");
您还可以添加接受超载行动 ,而不是Func键 ,如果你想执行一个不返回值的方法。
Answer 2:
听起来你正在做一个阻塞读/写。 你想要做什么是非阻塞的读/写。
有可能是一种方式来告诉你想非阻塞的COM端口。
你肯定超时不与commstudio工作? 也许你需要做一些特殊的初始化它们。
在任何情况下,你要读尽可能多的数据可能和如果没有可用的超时(取决于什么时候出来的值)。 你要不断循环而没有可用的数据没有错误,然后返回一个超时条件,如果没有什么用。
让你的阅读功能返回一个整数。 负值=误差值,例如,-1 =超时,字节的正数读......至少,这是我想做到这一点。
Answer 3:
对于水果盘,你可以只是测试,如果有什么可用的,然后做一个读的,而不是做不知道有一些东西还没有读阻塞。 就像是:
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--;
}
Answer 4:
如果有人想这样做在VB.Net,不要听那些谁说不能这样做! 您可能需要改变你的通用参数,以满足您的使用案例。
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
以及如何使用它的一个例子(我的是与Regex.Match
,有时熄灭到,如果模式包含了太多的外卡从来就不曾登陆:
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
文章来源: Implementing a timeout on a function returning a value