Reputation: 432
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 ?
Upvotes: 3
Views: 2745
Reputation: 101142
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
).
Upvotes: 6