在返回值的函数上实现超时

MGS*_*oto 11 .net c# timeout serial-port

我有一个函数,它在串行端口上调用读或写请求,然后返回读取的值.我正在使用Commstudio express(我正在实现Commstudio中的一个类),但它的超时功能似乎根本不起作用,所以我正在尝试实现自己的超时.目前我有一个定时器,根据请求设置读取或写入端口,如果定时器熄灭,回调将关闭连接导致异常.我试图让计时器的回调抛出一个异常,但异常需要通过调用原始读/写函数的线程传播,所以这样,它起作用,但我觉得它很混乱,那里必须是一个更好的方式来做我想要的.

Nat*_*lch 34

这是一个通用的解决方案,允许您在超时中包装任何方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

这就是你如何使用它:

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");
Run Code Online (Sandbox Code Playgroud)

如果要执行不返回值的方法,还可以添加接受Action而不是Func的重载.