While trying to figure out the new (maybe not so new now, but new to me, anyway) Task asynchronous programming in C#, I ran into a problem that took me a bit to figure out, and I'm not sure why.
I have fixed the problem, but I am still not sure why it was a problem to begin with. I just thought I'd share my experience in case anyone out there runs into the same situation.
If any gurus would like to inform me of the cause of the problem, that'd be wonderful and much appreciated. I always like knowing just why something doesn't work!
I made a test task, as follows:
Random rng = new Random((int)DateTime.UtcNow.Ticks);
int delay = rng.Next();
Task&Task&object&& testTask = Task.Factory.StartNew&Task&object&&(
async (obj) =&
DateTime startTime = DateTime.N
Console.WriteLine("{0} - Starting test task with delay of {1}ms.", DateTime.Now.ToString("h:mm:ss.ffff"), (int)obj);
await Task.Delay((int)obj);
Console.WriteLine("{0} - Test task finished after {1}ms.", DateTime.Now.ToString("h:mm:ss.ffff"), (DateTime.Now - startTime).TotalMilliseconds);
Task&Task&object&&[] tasks = new Task&Task&object&&[] { testTask };
Task.WaitAll(tasks);
Console.WriteLine("{0} - Finished waiting.", DateTime.Now.ToString("h:mm:ss.ffff"));
// make console stay open till user presses enter
Console.ReadLine();
And then I ran the application to see what it spat out. Here is some sample output:
6:06:15.5661 - Starting test task with delay of 3053ms.
6:06:15.5662 - Finished waiting.
6:06:18.5743 - Test task finished after ms.
As you can see, the Task.WaitAll(tasks); statement didn't do much. It waited a grand total of 1 millisecond before continuing execution.
I have answered my own "question" below - but as I said above - if anyone more knowledgeable than I would care to explain why this doesn't work, please do!
(I think it might have something to do with the execution 'stepping-out' of the method once it reaches an await operator - then stepping back in once the awaiting is done... But I am probably wrong)
解决方案 You should avoid using Task.Factory.StartNew with async-await. You should use Task.Run instead.
An async method returns a Task&T&, an async delegate does as well. Task.Factory.StartNew also returns a Task&T&, where its result is the result of the delegate parameter. So when used together it returns a Task&Task&T&&&.
All that this Task&Task&T&& does is execute the delegate until there's a task to return, which is when the first await is reached. If you only wait for that task to complete you aren't waiting for the whole method, just the part before the first await.
You can fix that by using Task.Unwrap which creates a Task&T& that represents that Task&Task&T&&&:
Task&Task& wrapperTask = Task.Factory.StartNew(...);
Task actualTask = wrapperTask.Unwrap();
Task.WaitAll(actualTask);
本文地址: &
虽然试图找出新的(也许没有现在这么新,但新的给我,反正)任务在C#中的异步编程,我遇到了那个花了问题我有点想不通,我不知道为什么。我有固定的问题,但我仍然不知道为什么它是开始的一个问题。我只是想在那里运行到了同样的情况我想分享一下我的情况下,任何人的经验。如果任何大师想告诉我这个问题的原因,那太好等等AP preciated。我总是喜欢知道刚为什么的东西不起作用!我做了一个测试任务,如下: 随机RNG =新的随机((INT)DateTime.UtcNow.Ticks);INT延迟= rng.Next();任务<任务<对象&> testTask = Task.Factory.StartNew<任务<对象&>(
异步(OBJ)=>
日期时间STARTTIME = DateTime.N
Console.WriteLine(“{0}
- 启动测试任务用的{1}毫秒的延迟。”,DateTime.Now.ToString(“H:毫米:ss.ffff”),(int)的物镜);
等待Task.Delay((int)的OBJ);
Console.WriteLine(“{0}
- 测试任务后,{1}毫秒完了。”DateTime.Now.ToString(“H:MM:ss.ffff”),(DateTime.Now
startTime时).TotalMilliseconds);
);任务<任务<对象&> [] =任务新任务<任务<对象&> [] {} testTTask.WaitAll(任务);Console.WriteLine(“{0}
- 已完毕等待。”DateTime.Now.ToString(“H:MM:ss.ffff”));//使控制台呆到用户presses进入到Console.ReadLine(); 然后我运行应用程序,看看它吐出来。下面是一些示例输出:
6:06:15.5661
- 从3053ms的延迟测试任务结果
6:06:15.5662
- 完毕等待结果。
6:06:18.5743
- 测试任务ms完成后。正如你所看到的, Task.WaitAll(任务); 声明没有做太多。它继续执行之前的总计1毫秒的等待着。我已经回答了我自己的“问题”的 - 但正如我上面所说的 - 如果任何人更了解比我会照顾解释为什么这不工作,请不要!(我的认为的一旦它到达一个的await 运营商可能有事情做与执行方法“走出出' - 再退一步在曾经的等待后...但我可能是错的)解决方案 您应该避免使用 Task.Factory.StartNew 与异步的await。您应该使用 Task.Run 代替。这是异步方法返回一个任务< T> ,异步委托确实也是如此。
Task.Factory.StartNew 还返回任务< T> ,其中,其结果是委托参数的结果。因此一起使用时,它返回一个任务<任务< T>>方式&
所有这任务<任务< T>> 做的是执行代表,直到有返回任务,达到第一的await时,这是。如果你只是等待任务完成,你是不是第一次的await之前等待整个方法,只是一部分。您可以修复使用 Task.Unwrap 这将创建一个任务< T> 的再presents的任务<任务< T>>> : 任务<任务> wrapperTask = Task.Factory.StartNew(...);任务actualTask = wrapperTask.Unwrap();Task.WaitAll(actualTask);
本文地址: &
扫一扫关注官方微信&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!【图文】第4章 任务间的同步与通信_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
第4章 任务间的同步与通信
上传于|0|0|文档简介
&&嵌入式操作系统基础
大小:4.85MB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢