【问题标题】:Task.Delay bugged or am I doing something wrong?Task.Delay 被窃听还是我做错了什么?
【发布时间】:2013-06-26 22:36:40
【问题描述】:

编辑:我做错了什么。问题是使用日期时间对象计时代码执行并输出毫秒而不是总毫秒。

简而言之,我有一个在 .net 4.5 上运行的新 mvc4 项目,主控制器中有以下代码。

    public async Task<ActionResult> Index()
    {
        Int32[] Delays = new Int32[] { 1999, 500, 20 }; 
        List<String> result = new List<String>();

        var now = DateTime.Now;

        result.Add(String.Format("Started at: {0}", now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")));

        //TAKE 1
        result.Add("Take 1");
        await Task.WhenAll(Delays.Select(async x => result.Add(await Slow(x, now, Array.IndexOf(Delays, x), "take 1"))));

        //TAKE 2
        result.Add("Take 2");
        var tasks = Delays.Select((x, i) => Slow(x, now, i, "take 2")).ToList();
        await Task.WhenAll(tasks);
        result.AddRange(tasks.Select(x => x.Result));

        return View(result);
    }

我的Slow方法是这样的……

    private async Task<String> Slow(Int32 ms, DateTime dt, int i, String take)
    {
        Response.Write(String.Format("[{3}][index:{0}][delay:{2}] pre sleep - {1} <br />", i, DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), ms, take));

        await Task.Delay(ms);

        Response.Write(String.Format("[{3}][index:{0}][delay:{2}] after sleep - {1} <br />", i, DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), ms, take));

        var delayedtime = DateTime.Now;

        var diff = delayedtime - dt;

        return String.Format("Slept for : [{2}]{0} miliseconds. diff was : {1}", ms, diff.Milliseconds, take);
    }

输出看起来像这样......

[take 1][index:0][delay:1999] pre sleep - 06/21/2013 02:46:25.338 PM
[take 1][index:1][delay:500] pre sleep - 06/21/2013 02:46:25.340 PM
[take 1][index:2][delay:20] pre sleep - 06/21/2013 02:46:25.340 PM
[take 1][index:2][delay:20] after sleep - 06/21/2013 02:46:25.368 PM
[take 1][index:1][delay:500] after sleep - 06/21/2013 02:46:25.849 PM
[take 1][index:0][delay:1999] after sleep - 06/21/2013 02:46:27.347 PM
[take 2][index:0][delay:1999] pre sleep - 06/21/2013 02:46:27.347 PM
[take 2][index:1][delay:500] pre sleep - 06/21/2013 02:46:27.347 PM
[take 2][index:2][delay:20] pre sleep - 06/21/2013 02:46:27.347 PM
[take 2][index:2][delay:20] after sleep - 06/21/2013 02:46:27.382 PM
[take 2][index:1][delay:500] after sleep - 06/21/2013 02:46:27.861 PM
[take 2][index:0][delay:1999] after sleep - 06/21/2013 02:46:29.359 PM

Started at: 06/21/2013 02:46:25.336 PM
Take 1
Slept for : [take 1]20 miliseconds. diff was : 32
Slept for : [take 1]500 miliseconds. diff was : 513
Slept for : [take 1]1999 miliseconds. diff was : 11
Take 2
Slept for : [take 2]1999 miliseconds. diff was : 23
Slept for : [take 2]500 miliseconds. diff was : 525
Slept for : [take 2]20 miliseconds. diff was : 46 

我对 1999 毫秒的延迟报告它在 5 毫秒后完成这一事实感到非常困惑,而其他两个延迟似乎工作得很好。 只要延迟参数高于“999”毫秒,我就会得到这种行为。

我的问题是我做错了什么,延迟是否响应了我不知道的配置,或者方法是否存在错误。

【问题讨论】:

  • result.Add 不是线程安全的。而是将其返回给任务。
  • async (x, index) =&gt; ...
  • @SLaks 我在这段代码中看不到任何多线程,所以我认为应该没问题。 (假设 Index() 没有在 ASP.NET 上下文之外调用,但我认为这是一个安全的假设。)
  • @svick 即便如此,它仍然是糟糕的设计。任务最好将该值设置为结果,然后通过WhenAll 的返回值捕获结果集合。如果任务在不同的上下文中运行,它会更容易编码,对读者来说更清晰,并且是一种没有破坏风险的范例。
  • @svick:你不知道Task.Delay() 会回调哪些(或多少)线程

标签: c# asp.net-mvc-4 .net-4.5 async-await


【解决方案1】:

diff.Milliseconds 测量时间跨度的毫秒部分。也许你的意思是:

diff.TotalMilliseconds

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    相关资源
    最近更新 更多