Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a timeout on a function returning a value

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.

like image 627
MGSoto Avatar asked Sep 03 '09 00:09

MGSoto


People also ask

How to apply TIMEOUT function using thread in Python?

Applying timeout function using thread in Python. If we want to implement timeout a function we need two threads-. 1. The first thread is to execute the function. 2. The second thread is to measure the time taken by the function. The only second thread should whether the time is over or not. In this approach, we can not kill ...

Is it possible to terminate a function after it reaches timeout?

Be careful since this does not terminate the function after timeout is reached! Note that on Windows, this spawns an entirely new process - which will eat into the time to timeout, perhaps by a lot if the dependencies take a long time to set up. Yes, this needs some tweaking. It leaves threads going forever.

How do I throw an exception when using ontimeout?

Here, the onTimeout function is set up to throw an exception: Func<bool> onTimeout = () => { // in this scenario, we want to receive an exception throw new TimeoutException ( "The function was to slow." ); }; In the example code, I added [TestMethod] attributes, which allow for executing and debugging these example functions from Visual Studio.

What does the start method in the timeoutprocess class do?

The Start method in the TimeoutProcess class blocks the calling thread for the specified time or until the process completes. Sometimes, we may have to run many processes simultaneously and each with a timeout limit.


2 Answers

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:

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

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

like image 115
Nathan Baulch Avatar answered Sep 19 '22 16:09

Nathan Baulch


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.

like image 42
hookenz Avatar answered Sep 20 '22 16:09

hookenz