static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();
Task[] tasks = new Task[1];
tasks[0] = Task.Run(() =>
{
IPHostEntry iphe = Dns.GetHostEntry("8.8.8.8.dnsrbl.org");
});
Task.WaitAll(tasks, 2000);
Console.WriteLine("Done in " + stopwatch.ElapsedMilliseconds + " ms");
}
8.8.8.8.dnsrbl.ru
是一个最终会超时的查询示例。我认为没有工作的DNS服务器(或其防火墙正在阻止我)。
无论如何,关键不在于从DNS服务器获取结果,而在于当等待包含对Dns.GetHostEntry()
的调用的任务时,Task.WaitAll()
在Windows和Mono上的行为如何。
在Windows上,当查询在超时期限(2s)内未返回任何结果时,程序运行需要大约2秒钟。也就是说,带有超时的Task.WaitAll似乎起作用。在使用Mono在Linux上运行此程序需要2秒才能获得输出,但是该程序直到任务退出后才终止。为什么会这样呢?
无论是否使用带有超时的Time.WaitAll,我似乎都得到相同的执行时间。
Dns.GetHostEntry()
的关键在于,如果我启动具有Thread.Sleep()
的任务来模拟长时间运行的任务,则Task.WaitAll()
按预期工作。下面是可以正常工作的示例代码:
tasks[0] = Task.Run(() => Thread.Sleep(10000));
有没有一种方法可以强制Task.WaitAll(Task [] tasks,int millisecondsTimeout)
在Mono中运行时实际超时?
编辑:Task.WaitAll()确实在超时后返回,但是在Mono中运行时程序不会终止(直到Dns.GetHostEntry
超时)。
这不是编译器的问题。无论我使用Visual Studio还是Mono C#编译器编译,都会得到相同的结果。
Task.WaitAll
即使在Mono上也会正确超时(输出显示为2秒,这意味着 Task.WaitAll 在2秒内返回)。 - EvkTask.WaitAll
时,在两个环境中都立即完成(如预期)。 - Jeff MerlinThread.Sleep(2000)
并退出呢? - EvkDns.GetHostEntry
会启动新的非后台线程。程序无法完成,直到所有非后台线程都完成。确认这一点很困难,因为在Mono中,Dns.GetHostEntry
最终会调用一些难以分析(甚至难以找到)源代码的本地函数。 - Evk