Can I write a general purpose method to call other methods with a timeout?

I have a problem that is undoubtedly familiar to many: I make a call (more precisely, it is Forest.GetCurrentForest ()), which in some cases will not work and will throw an exception. Not a huge problem, just catch it and give it your due attention. However, the call when it fails is very slow; it takes 30 seconds to complete.

I went looking for a way to call this method, but set up a timeout so that we can stop after a shorter time. I found an interesting suggestion here , but I would like a more general solution if I can handle it. This solution is also quite heavy for additional features to get timeout. I was hoping it would be as easy as, say,

CallMethodWithTimeout(Delegate method, int timeout)

      

But I'm not sure if something like this would work. Any suggestions on how to do this, or is it just not possible in C #? We are also sticking to .NET 2.0.

If you disagree with this, I'll comment on the observance of the GetCurrentForest () call in 30 seconds to understand that this is not happening. Though I would like to know about the possibility of this method calling a method of a common method.

+2


source to share


2 answers


I thought a bit and came up with the following method (which is essentially an implementation of what Michael wrote when I coded it):

private static bool TimedMethodCaller(Delegate dlgt, int timeout, 
    params object[] args)
{
    ManualResetEvent waitHandle = new ManualResetEvent(false);
    Thread t = new Thread(new ThreadStart(delegate
        {
            dlgt.Method.Invoke(dlgt.Target, args);
            waitHandle.Set();
        }));
    t.Start();
    return waitHandle.WaitOne(timeout);
}

      

Using this method, you can publish it in any item and parameters you like. This has the disadvantage that it doesn't handle return values ​​(but this can probably be achieved in some way as well).

You can call it like this:



// parameter-less method call
bool success = TimedMethodCaller(new Action(ParamlessTestMethod), 100);

      

If you want to call a method that takes parameters, you need a suitable delegate:

// call with one parameter (using the Action<T> delegate of the framework
bool success = TimedMethodCaller(new Action<int>(TestMethod), 100, "text"); 

// call with several parameters using custom delegate that is defined like this:
// public delegate void SampleDelegate(string text, int numeric);
bool success = TimedMethodCaller(new SampleDelegate(TestMethod), 100, "text", 1);

      

+2


source


You cannot directly undo invalidable operations ( this link describes some of the problems with asynchronous exceptions in code that was not hardened for it.)



One pattern I've seen is to put a queue to work on a different thread, but only wait for a limited time for it to complete, effectively abandoning the request when it takes too long. This does not override the entitlement, but it can help your application to be responsive.

+2


source







All Articles