对返回值的函数实现超时
我有一个函数可以在串行端口上发出读取或写入请求,然后返回读取的值。我正在使用 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是一个通用解决方案,允许您在超时中包装任何方法:
http://kossovsky.net/index.php/2009/07/csharp-how-to-limit-method-execution-time/
它使用有用的 Thread.Join 重载接受以毫秒为单位的超时,而不是手动使用计时器。我唯一要做的不同就是交换成功标志和结果值以匹配 TryParse 模式,如下所示:
这就是您使用它的方式:
您还可以添加接受 操作 而不是 Func 如果你想执行一个不返回值的方法。
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/
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:
And this is how you would use it:
You could also add overloads that accept Action instead of Func if you want to execute a method that doesn't return a value.
听起来你正在执行阻塞读/写操作。您想要做的是非阻塞读/写。
可能有一种方法可以告诉 com 端口您想要非阻塞。
您确定超时不适用于 commstudio 吗?也许你必须做一些特殊的事情来初始化它们。
在任何情况下,您都希望读取尽可能多的数据,如果没有可用的数据,则超时(取决于超时的值是多少)。您需要在没有可用数据且没有错误的情况下继续循环,然后在没有任何可用数据时返回超时条件。
让您的读取函数返回一个整数。负值=错误值,例如-1=超时,读取的正字节数...至少我就是这样做的。
Sounds like you're doing a blocking read/write. What you want to do is a non-blocking read/write.
There is probably a way to tell the com port that you're wanting non- blocking.
Are you sure the timeouts are not working with commstudio? maybe you have to do something special to initialise them.
In any case, you want to read as much data as possible and if none is available time out (depending on what the value of the time out is). You'll want to keep looping while no data available and no error and then return a time out condition if there wasn't anything available.
Make your read function return an integer. negative values = error value e.g. -1 = timeout, positive number of bytes read... at least thats the way I'd do it.
您可以创建一个扩展方法,该方法将
Task
和T
类型的defaultValue
作为输入。这是我的实现。这是一个用法示例:
You can create an extension method that takes the
Task<T>
and adefaultValue
of typeT
as input. Here is my implementation.Here is a usage example:
对于comport,您可以只测试是否有任何可用的东西,然后进行读取,而不是在不知道还有什么东西的情况下进行阻塞读取。像这样的东西:
For the comport you could just test if there is anything available and then do a read instead of doing a blocking read without knowing there is something yet. Something like:
如果有人想在 VB.Net 中做到这一点,请不要听那些说做不到的人的话!
您可能需要更改通用参数以适合您的用例。
以及如何使用它的一个示例(我的示例是使用
Regex.Match
,如果模式包含太多通配符,有时会出现“never never land”的情况:In case someone wants to do this in VB.Net, don't listen to those who say it can't be done!
You may need to alter your generic parameters to suit your use case.
And an example of how to use it (mine was with
Regex.Match
, which sometimes goes off into never never land if the patterns contains too many wild cards: