在返回值的函数实现了超时(Implementing a timeout on a function

2019-07-04 13:12发布

我有召唤出一个串口读取或写入请求,然后返回读取值的函数。 我使用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