Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return value from Action

Tags:

c#

.net

delegates

I have a Proxy testing function. Inside it I have a catch block and after a specified amount of time (TIMEOUT) if the proxy is not good I return a false flag. The problem is that once every 10 times the function hangs even though there's no exception present . Practically the HttpWebResponse.Timeout doesn't work correctly (or maybe it does but I don't know how to use it). So a SO user gave me this solution:

public class TimeoutInvoker
{
    public static void Run(Action action, int timeout)
    {
        var waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
        AsyncCallback callback = ar => waitHandle.Set();
        action.BeginInvoke(callback, null);

        if (!waitHandle.WaitOne(timeout))
            throw new TimeoutException("Timeout.");
    }
}

and use it like this:

TimeoutInvoker.Run(()=>ProxyIsGood(ip, port));

The problem is that I need to use it like this , with a return value :

while( !(TimeoutInvoker.Run(()=>ProxyIsGood(ip, port)) )
{
    reset_stuff();
}

So how do I modify TimeoutInvoker ?

like image 237
kawa Avatar asked Aug 21 '26 06:08

kawa


1 Answers

You have to call EndInvoke to retrieves the result of an asynchronous call.

Change your class to:

public class TimeoutInvoker
{
    public static TResult Run<TResult>(Func<TResult> action, int timeout)
    {
        var waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
        AsyncCallback callback = ar => waitHandle.Set();

        IAsyncResult result = action.BeginInvoke(callback, null);

        if (!waitHandle.WaitOne(timeout))
            throw new TimeoutException("Timeout.");

        return action.EndInvoke(result);
    }
}

or use a Task and Task.Wait:

public class TimeoutInvoker
{
    public static TResult Run<TResult>(Func<TResult> action, int timeout)
    {
        var task = Task.Factory.StartNew(action);

        if (task.Wait(timeout)) 
            return task.Result;

        throw new TimeoutException("Timeout.");
    }
}

Note that this will simply throw an exception when the timeout is hit (and does not make use of a CancellationToken).

like image 64
sloth Avatar answered Aug 22 '26 19:08

sloth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!