我正在尝试为不支持CancellationToken或预定义超时的WCF调用实施超时机制。为此,我创建了一个小项目并提出了以下结构:
var st = Stopwatch.StartNew();
try
{
var responseTask = Task.Run(() =>
{
var task = new WaitingService.ServiceClient().GetDataAsync(60000);
if (!task.Wait(1000))
{
return null;
}
return task.Result;
});
await responseTask;
}
catch { }
return Ok("Awaited for " + st.ElapsedMilliseconds + "ms. Supposed to be " + sleep);
[当我在本地计算机上顺序运行此代码时(一次调用1次),输出非常非常接近1000,丢失约10至50ms,这是100%可以接受的。但是,如果我以并发方式运行,比如说一次5个请求,它开始滑落到100毫秒...如果我对25个并发请求运行,我开始在几秒钟内看到滑移,当我运行时高于35时,滑移率优于10秒(这时我将睡眠增加到60秒,因为服务在框架可以“注意到”它超时之前返回)
谁能告诉我这是怎么回事?为什么这种“滑移”发生在这样的程度?我要实现的目标是否有更可靠的实现?
详细信息:服务非常简单:
我也测试了这种情况:public string GetData(int value) { Console.WriteLine("Will sleep for " + value); Thread.Sleep(value); return string.Format("Slept for: {0}ms", value); }
编辑1
var st = Stopwatch.StartNew(); CancellationTokenSource src = new CancellationTokenSource(1000); try { var responseTask = Task.Run(() => { var task = new WaitingService.ServiceClient().GetDataAsync(sleep); if (!task.Wait(1000,src.Token)) { return null; } task.Wait(src.Token); return task.Result; }); await responseTask; } catch { } return Ok("Awaited for " + st.ElapsedMilliseconds + "ms. Supposed to be " + sleep);
但是我实际上得到了更差的结果...滑倒加剧了...
我正在尝试为不支持CancellationToken或预定义超时的WCF调用实施超时机制。为此,我创建了一个小项目,并提出了以下结构:...
假设您的进程中有10个线程,并且这些线程以循环方式进行调度,其中每个线程仅获得2毫秒的执行时间。假设如果所有10个线程在第0毫秒启动,并且StopWatch
的20毫秒过去,则每个线程仅获得4毫秒的执行时间,其余16毫秒,每个线程将等待轮流执行。因此,如果您使用特定的超时值将特定的线程阻塞了一定的毫秒数,这并不意味着该线程的执行将在指定的时间内完成。