在返回值的函数上实现超时 [英] Implementing a timeout on a function returning a value

查看:20
本文介绍了在返回值的函数上实现超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a function that calls out a read or write request on a serial port and then returns the value that was read. I am using Commstudio express (I'm implementing a class from Commstudio) , but it's timeout features don't appear to work at all, so I'm trying to implement my own timeout. Currently I have a timer that is set upon request to read or write to the port, and if the timer goes off, the callback closes the connection causing an exception. I tried to have the callback of the timer throw an exception, but the exception needs to be propagated up through the thread that was calling the original read/write function, so in this way, it works, but I feel like it's messy and there must be a better way to do what I want.

推荐答案

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

Here is a generic solution that allows you to wrap any method in a timeout:

http://kossovsky.net/index.php/2009/07/csharp-how-to-limit-method-execution-time/

它使用有用的 Thread.Join 重载,它接受一个以毫秒为单位超时,而不是手动使用计时器.我唯一不同的是交换成功标志和结果值以匹配 TryParse 模式,如下:

It uses the useful Thread.Join overload that accepts a timeout in milliseconds rather than manually using timers. The only thing I would do differently is swap the success flag and result value to match the TryParse pattern, as follows:

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;
}

这就是你将如何使用它:

And this is how you would use it:

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");

您也可以添加接受 Action 的重载Func 如果你想执行一个不返回的方法一个值.

You could also add overloads that accept Action instead of Func if you want to execute a method that doesn't return a value.

这篇关于在返回值的函数上实现超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆