在过去的几天里,我testing了.net 4.5和c#5的新特性。 我喜欢它的新asynchronous/等待function。 早些时候,我曾经使用BackgroundWorker在响应式UI的背景下处理更长的stream程。 我的问题是:有了这些很好的新function,什么时候应该使用async / await和BackgroundWorker ? 哪两个都是常见的情况?
我正在使用完全asynchronous的API客户端,即每个操作都返回Task或Task<T> ,例如: static async Task DoSomething(int siteId, int postId, IBlogClient client) { await client.DeletePost(siteId, postId); // call API client Console.WriteLine("Deleted post {0}.", siteId); } 使用C#5 async / await运算符,启动多个任务并等待它们全部完成的正确/最有效的方法是: int[] ids = new[] { 1, 2, 3, 4, 5 }; Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait()); 要么: int[] ids = new[] { 1, 2, 3, 4, […]
我可能会失去一些东西,但做什么之间的区别: public void MyMethod() { Task t = Task.Factory.StartNew(DoSomethingThatTakesTime); t.Wait(); UpdateLabelToSayItsComplete(); } public async void MyMethod() { var result = Task.Factory.StartNew(DoSomethingThatTakesTime); await result; UpdateLabelToSayItsComplete(); } private void DoSomethingThatTakesTime() { Thread.Sleep(10000); }
TL; DR: 由StaTaskScheduler运行的任务内的死锁。 长版本: 我使用Parallel Team的ParallelExtensionsExtras中的StaTaskScheduler来托pipe由第三方提供的一些传统的STA COM对象。 StaTaskScheduler实现细节的描述如下: 好消息是TPL的实现能够在MTA或者STA线程上运行,并且考虑到WaitHandle.WaitAll(当方法提供了多个等待句柄时只支持MTA线程)等底层API的相关差异。 我认为这意味着TPL的阻塞部分将使用一个等待API的消息,如CoWaitForMultipleHandles ,以避免在STA线程上调用死锁情况。 在我的情况下,我相信以下情况正在发生:进程内的STA COM对象A调用了对象之外的对象B,然后期望从B通过作为传出呼叫的一部分的callback。 简化forms: var result = await Task.Factory.StartNew(() => { // in-proc object A var a = new A(); // out-of-proc object B var b = new B(); // A calls B and B calls back A during the Method call return a.Method(b); }, […]
我碰到一些使用c#的async / await关键字进行异步编程的最佳实践(我是c#5.0的新手)。 其中一个建议是: 稳定性:了解您的同步上下文 …一些同步上下文是不可重入和单线程的。 这意味着在给定的时间只能在上下文中执行一个工作单元。 这个例子是Windows UI线程或ASP.NET请求上下文。 在这些单线程的同步上下文中,自己很容易死锁。 如果你从一个单线程上下文中产生一个任务,那么等待上下文中的任务,你的等待代码可能会阻塞后台任务。 public ActionResult ActionAsync() { // DEADLOCK: this blocks on the async task var data = GetDataAsync().Result; return View(data); } private async Task<string> GetDataAsync() { // a very simple async method var result = await MyWebService.GetDataAsync(); return result.ToString(); } 如果我自己尝试剖析它,主线程会在“MyWebService.GetDataAsync();”中生成一个新线程,但是由于主线程在那里等待,它将等待“GetDataAsync()。Result”的结果。 同时,说数据已经准备好了。 为什么主线程不继续它的继续逻辑,并从GetDataAsync()返回字符串结果? 有人可以解释一下为什么在上面的例子中有一个僵局? 我完全不知道问题是什么