Tag: async await

在其之前创建Form时,其中包含Application循环的NUnit测试会挂起

我有一些使用MessageLoopWorker包装的WebBrowser控件的测试,如下所述: WebBrowser Control在一个新线程中 但是当另一个测试创建用户控件或表单时,测试会冻结并永远不会完成: [Test] public async Task WorksFine() { await MessageLoopWorker.Run(async () => new {}); } [Test] public async Task NeverCompletes() { using (new Form()) ; await MessageLoopWorker.Run(async () => new {}); } // a helper class to start the message loop and execute an asynchronous task public static class MessageLoopWorker { public static […]

ContinueWith失去SynchronizationContext

在下面的代码段中, SynchronizationContext将丢失,因此还有CurrentCulture和CurrentUICulture 。 Log()来自这个答案 。 public async Task Index() { Log(“before GetAsync”); await new HttpClient().GetAsync(“http://www.example.com/”) .ContinueWith(request => { Log(“ContinueWith”); request.Result.EnsureSuccessStatusCode(); }, TaskContinuationOptions.AttachedToParent); return View(); } static void Log(string message) { var ctx = System.Threading.SynchronizationContext.Current; System.Diagnostics.Debug.Print(“{0}; thread: {1}, context: {2}, culture: {3}, uiculture: {4}”, message, System.Threading.Thread.CurrentThread.ManagedThreadId, ctx != null ? ctx.GetType().Name : String.Empty, System.Threading.Thread.CurrentThread.CurrentCulture.Name, System.Threading.Thread.CurrentThread.CurrentUICulture.Name); } […]

等待成千上万的任务

我有一个应用程序,通常有1.000 – 30.000文件转换一些数据。 我需要做3个步骤: 复制文件(替换那里的一些文字) 使用WebClient创建Webrequest以下载文件(我将复制的文件发送到WebServer,将文件转换为另一种格式) 获取下载的文件并更改部分内容 所以这三个步骤包括一些I / O,我使用了async / await方法: var tasks = files.Select(async (file) => { Item item = await createtempFile(file).ConfigureAwait(false); await convert(item).ConfigureAwait(false); await clean(item).ConfigureAwait(false); }).ToList(); await Task.WhenAll(tasks).ConfigureAwait(false); 我不知道这是否是最好的做法,因为我创造了超过一千个任务。 我想过将这三个步骤拆分为: List items = new List(); var tasks = files.Select(async (file) => { Item item = await createtempFile(file, ext).ConfigureAwait(false); lock(items) items.Add(item); }).ToList(); await […]

EF6 ToListAsync冻结Winforms

我有一个简单的Winforms应用程序,上面有一个按钮。 首先使用EF 6.1.1代码,如果我在查询中使用.ToListAsync,它将冻结表单,直到结果从SQL Server返回。 private async void button1_Click(object sender, EventArgs e) { using( var context = new MyEFContext() ) { var result = await context.MyTable.ToListAsync(); MessageBox.Show(result.Count); } } 如果我将.ToListAsync()调用放在不同的同步上下文中,可以通过在它之前添加await Task.Delay(1).ConfigureAwaiter(false)来实现它的工作原理。 有人知道我在这里缺少什么吗? 为什么会这样?

Await阻止UI线程,网络相关

我在我的Windowsapp store应用中有这段代码,我点击了按钮。 但不知何故,当我在极少数情况下单击此按钮时,UI会冻结。 当我连接到比通常连接的Wi-Fi网络更远的Wi-Fi网络时,通常会发生这种情况。 考虑到我从互联网上下载RSS源,很可能与我使用async / await关键字有关。 如果我正确理解async / await的机制,UI线程根本不应该阻塞。 我在这里错过了什么吗? private async void Add_Click(object sender, RoutedEventArgs e) { AddButton.Visibility = Windows.UI.Xaml.Visibility.Collapsed; DownloadProgressRing.Visibility = Windows.UI.Xaml.Visibility.Visible; DownloadProgressRing.IsActive = true; RssData rssData = App.Current.Resources[“rssData”] as RssData; Uri uri = FixUrl(RssUrl.Text); if (uri != null) { newRssFeed = new RssFeed(uri.ToString()); Task success = newRssFeed.RetrieveFeed(); if (await success) { […]

即使没有异步,CallContext.LogicalGetData也会被恢复。 为什么?

我注意到CallContext.LogicalSetData/LogicalGetData不按我预期的方式工作。 即使没有异步或任何类型的线程切换 , async方法中设置的值也会被恢复。 这是一个简单的例子: using System; using System.Runtime.Remoting.Messaging; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication { class Program { static async Task TestAsync() { CallContext.LogicalSetData(“valueX”, “dataX”); // commented out on purpose // await Task.FromResult(0); Console.WriteLine(CallContext.LogicalGetData(“valueX”)); return 42; } static void Main(string[] args) { using(ExecutionContext.SuppressFlow()) { CallContext.LogicalSetData(“valueX”, “dataXX”); Console.WriteLine(CallContext.LogicalGetData(“valueX”)); Console.WriteLine(TestAsync().Result); Console.WriteLine(CallContext.LogicalGetData(“valueX”)); } } } } 它产生这个输出: […]

基于非实现接口的通用约束

我有一个带有工厂服务的应用程序,允许构建实例,同时解决必要的dependency injection。 例如,我使用它来构建对话框视图模型。 我有一个服务接口,如下所示: public interface IAsyncFactory { Task Build() where T: class, IAsyncInitialize; } 理想情况下,我想拥有的是这样的(伪语法,因为这不是直接可实现的) public interface IFactory { Task Build() where T: class, IAsyncInitialize; T Build() where T: class, !IAsyncInitialize; } 这里的想法是,如果一个类支持IAsyncInitialize ,我希望编译器解析为返回Task的方法,以便从消费代码中明显看出它需要等待初始化。 如果该类不支持IAsyncInitialize ,我想直接返回该类。 C#语法不允许这样做,但是有不同的方法来实现我的目标吗? 这里的主要目标是帮助提醒消费者类的实例化它的正确方法,这样对于具有异步初始化组件的类,我不会在初始化之前尝试使用它。 我能想到的最接近的是创建单独的Build和BuildAsync方法,如果为IAsyncInitialize类型调用Build,则会出现运行时错误,但这没有在编译时捕获错误的好处。

使用带参数的异步任务方法注册新的pageasynctask

我在asp.net webforms项目中有这个方法: private async Task SomeMethod(int accID){ // } 我想在page_load中执行此操作,但我不确定如何处理参数。 protected void Page_Load(object sender, EventArgs e) { RegisterAsyncTask(new PageAsyncTask(SomeMethod(int accID))); // etc }

Windows Phone 8异步等待使用

我刚刚开始学习WP编程,所以这可能是一个愚蠢的问题…… 我开发的应用程序从一个Web服务获取数据几个不同的方法。 所以我决定将所有这些Web服务提取代码放到一个类中: class WebApiWorker { public async Task<List> GetGeocodeAsync(String address) { String url = “http://api.com&search=” + HttpUtility.UrlEncode(address) + “&format=json”; HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); httpWebRequest.Method = “GET”; HttpWebResponse response = (HttpWebResponse) await httpWebRequest.GetResponseAsync(); Stream responseStream = response.GetResponseStream(); string data; using (var reader = new System.IO.StreamReader(responseStream)) { data = reader.ReadToEnd(); } responseStream.Close(); var geocodeResponse = JsonConvert.DeserializeObject<List>(data); […]

Microsoft.Bcl.Async中是否存在ExceptionDispatchInfo的模拟?

Microsoft.Bcl.Async中是否存在ExceptionDispatchInfo的模拟? 我找不到类似的东西。 这个问题是由我的另一个问题引发的。 当exception的父task可用时,我可以使用task.GetAwaiter().GetResult()来重新抛出,如@StephenCleary所建议的那样。 当它不可用时,我有哪些选择?