我有一个代理测试功能。在其中我有一个 catch block ,在指定的时间(超时)后,如果代理不好,我会返回一个错误标志。问题是,即使没有异常,函数每 10 次就会挂起一次。实际上 HttpWebResponse.Timeout 无法正常工作(或者可能可以,但我不知道如何使用它)。所以一位 SO 用户给了我这个解决方案:
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.");
}
}
并像这样使用它:
TimeoutInvoker.Run(()=>ProxyIsGood(ip, port));
问题是我需要像这样使用它,并带有返回值:
while( !(TimeoutInvoker.Run(()=>ProxyIsGood(ip, port)) )
{
reset_stuff();
}
那么如何修改 TimeoutInvoker ?
最佳答案
您必须调用 EndInvoke
来检索异步调用的结果。
将您的类(class)更改为:
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);
}
}
或使用Task
和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.");
}
}
请注意,当超时时,这只会引发异常(并且不使用 CancellationToken
)。
关于c# - 如何从 Action 中返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24262309/