Tag: async await

异步等待和线程

基于我在MSDN上阅读的内容 async和await关键字不会导致创建其他线程。 异步方法不需要multithreading,因为异步方法不能在自己的线程上运行。 该方法在当前同步上下文上运行,并且仅在方法处于活动状态时才在线程上使用时间。 您可以使用Task.Run将CPU绑定的工作移动到后台线程,但后台线程无法帮助只等待结果可用的进程。 它基本上是说不会创建任何线程。 但是在我inheritance了HttpClient的类中,我发现了一些有趣的东西.. async Task SendAsync(HttpMethod method, Uri uri, HttpContent content, CancellationToken cancellationToken) { HttpRequestMessage msg = new HttpRequestMessage(method, uri); msg.Content = content; //On Main Thread HttpResponseMessage response = await SendAsync(msg, cancellationToken); //On worker thread //… } 该方法在static void Main调用 Task result = client.GetAsync(…); //GetAsync calls await SendAsync result.Wait(); 在await SendAsnc调用后,为什么我在一个单独的线程? […]

async和await关键字不会导致创建其他线程吗?

我糊涂了。 一个或多个Task如何在一个线程上并行运行? 我对并行性的理解显然是错误的。 MSDN的比特我无法理解: async和await关键字不会导致创建其他线程。 异步方法不需要multithreading,因为异步方法不能在自己的线程上运行。 该方法在当前同步上下文上运行,并且仅在方法处于活动状态时才在线程上使用时间。 ..和: 在启动任务和等待任务之间,您可以启动其他任务。 其他任务隐式并行运行,但不会创建其他线程。

从C#AsyncCTP使用ExecuteReaderAsync的任何缺点

有一些文章指出异步数据库调用在.NET中是个坏主意。 我的数据库调用应该是异步的吗? 我的数据库调用应该是异步第二部分 在C#Async CTP上,有一个名为ExecuteReaderAsync的System.Data.SqlClient.SqlCommand扩展。 我在现有代码上有如下操作: var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[“hubConnectionString”].ConnectionString; using (var conn = new SqlConnection(connectionString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = “sp$DetailsTagsGetAllFromApprovedPropsWithCount”; cmd.CommandType = System.Data.CommandType.StoredProcedure; conn.Open(); var reader = cmd.ExecuteReader(); while (reader.Read()) { //do the reading } conn.Close(); } } 我的代码上有几个这样的操作。 所以,我正在考虑将这些转换为异步。 但另一方面,我对这种方法没有太多的吸引力(也许我没有看到正确的方向,谁知道!)。 那么,在这里使用这种新的异步编程模型有什么缺点吗? 编辑: 假设我重构代码如下: public […]

在异步方法中避免异步和等待

一个简单的问题; 阅读本文: http : //blog.stephencleary.com/2016/12/eliding-async-await.html 它通常告诉我,使用async / await。 已经这样做了。 但是,他也说你在代理任务时不必使用异步部分。 // Simple passthrough to next layer: elide. Task PassthroughAsync(int x) => _service.DoSomethingPrettyAsync(x); // Simple overloads for a method: elide. async Task DoSomethingPrettyAsync(CancellationToken cancellationToken) { … // Core implementation, using await. } 为什么在通过时不应该使用async / await? 这不是那么方便,这甚至有意义吗? 任何想法?

异步使用同步WCF服务

我目前正在将客户端应用程序迁移到.NET 4.5以使用async / await。 该应用程序是WCF服务的客户端,该服务目前仅提供同步服务。 我现在想知道, 我应该如何异步使用这种同步服务 ? 我正在使用渠道工厂连接到WCF服务,利用服务器和客户端共享的服务合同。 因此,我无法使用VisualStudio或svcutil的自动生成来生成异步客户端代理。 我已经阅读了这个相关的问题 , 该问题是关于是否使用Task.Run在客户端包装同步调用,或者是否使用异步方法扩展服务契约。 答案表明,服务器提供的“真正的”异步方法对于客户端性能更好,因为没有线程必须主动等待服务调用完成。 这对我来说很有意义,这意味着同步调用应该包含在服务器端。 另一方面,Stephen Toub在这篇博文中总体上拒绝这样做。 现在,他没有在那里提到WCF,所以我不确定这是否只适用于在同一台机器上运行的库,或者它是否也适用于远程运行的东西,但是异步性的引入对其有实际影响。连接/传输。 毕竟,由于服务器实际上并不是异步工作(并且可能不会在另一个时间内工作),因此某些线程将始终必须等待:在客户端或服务器上。 这同样适用于同步使用服务(当前,客户端在后台线程上等待以保持UI响应)。 例 为了使问题更清楚,我准备了一个例子。 完整项目可在此处下载 。 服务器提供同步服务GetTest 。 这是当前存在的,并且工作同步发生的地方。 一种选择是将其包装在异步方法中,例如使用Task.Run ,并将该方法作为合同中的附加服务提供(需要扩展合同接口)。 // currently available, synchronous service public string GetTest() { Thread.Sleep(2000); return “foo”; } // possible asynchronous wrapper around existing service public Task GetTestAsync() { return Task.Run(() […]

async Task vs async void

这可能是一个非常愚蠢的问题,但我有以下编码行将RAW图像转换为BitmapImages: public async void CreateImageThumbnails(string imagePath, int imgId) { await Task.Run(() => controlCollection.Where(x => x.ImageId == imgId).FirstOrDefault().ImageSource = ThumbnailCreator.CreateThumbnail(imagePath)); } 调用此方法CreateThumbnail() public static BitmapImage CreateThumbnail(string imagePath) { var bitmap = new BitmapImage(); using (var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read)) { bitmap.BeginInit(); bitmap.DecodePixelWidth = 283; bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.StreamSource = stream; bitmap.EndInit(); } bitmap.Freeze(); GC.WaitForPendingFinalizers(); […]

创建异步Web服务方法

我试图阅读异步方法,现在我正在尝试创建自己的异步方法。 该方法是一个webservice调用,它返回错误日志列表。 我不确定我是否理解正确,所以我想我会分享我的代码,看看我是否应该做任何不同的事情。 我想要的代码就是通过调用方法GetAllErrorLogs()来返回错误日志列表,这是一个同步方法。 因为我可能需要一秒钟来获取所有错误日志,所以当我调用GetAllErrorLogs()方法时,我希望有机会做其他的事情。 这是代码。 [WebMethod] public async Task<List> GetAllErrorLogs() { List errorLogs = new List(); await System.Threading.Tasks.Task.Run(() => { errorLogs = ErrorLogRepository.GetAllErrorLogs(); }); if (errorLogs == null) return new List(); return errorLogs; } 谢谢!

处理包装任务的有限并发级别任务调度程序(具有任务优先级)

我很难找到一个任务调度程序,我可以在其上安排优先级任务,但也可以处理“包装”任务。 它类似于Task.Run尝试解决的问题,但您无法为Task.Run指定任务计划Task.Run 。 我一直在使用Parallel Extensions Extras Samples中的QueuedTaskScheduler来解决任务优先级要求(也是本文的建议)。 这是我的例子: class Program { private static QueuedTaskScheduler queueScheduler = new QueuedTaskScheduler(targetScheduler: TaskScheduler.Default, maxConcurrencyLevel: 1); private static TaskScheduler ts_priority1; private static TaskScheduler ts_priority2; static void Main(string[] args) { ts_priority1 = queueScheduler.ActivateNewQueue(1); ts_priority2 = queueScheduler.ActivateNewQueue(2); QueueValue(1, ts_priority2); QueueValue(2, ts_priority2); QueueValue(3, ts_priority2); QueueValue(4, ts_priority1); QueueValue(5, ts_priority1); QueueValue(6, ts_priority1); Console.ReadLine(); } private […]

对WCF服务的异步调用不会保留CurrentCulture

根据这个问题的答案async/await call应该保留CurrentCulture。 就我而言,当我调用自己的异步方法时,将保留CurrentCulture。 但是,如果我调用某种WCF服务方法,则不会保留CurrentCulture,而是将其更改为看起来像服务器默认线程文化的东西。 我查看了调用托管线程的内容。 它发生在每个代码行都在一个托管线程上执行(ManagedThreadId保持不变)。 在调用我自己的异步方法后,CultureInfo保持不变。 但是当我调用WCF的方法时,ManagedTrheadId保持不变,但CurrentCulture已更改。 简化的代码如下所示:: private async Task Test() { // Befoe this code Thread.CurrentThread.CurrentCulture is “ru-RU”, ie the default server’s culture // Here we change current thread’s culture to some desired culture, eg hu-HU Thread.CurrentThread.CurrentCulture = new CultureInfo(“hu-HU”); var intres = await GetIntAsync(); // after with await Thread.CurrentThread.CurrentCulture is still […]

使用async / await与DataReader? (没有中间缓冲区!)

我的目标很简单,我想做异步I / O调用(使用异步等待) – 但是: 不使用DataFlow依赖( 如在此答案中 ) 没有中间缓冲区( 不像这个答案 ) Projector函数应作为参数发送。 ( 不是这个答案 ) 好。 目前这里是我的代码,它的工作是从db读取并将每一行投影到Func public IEnumerable GetSomeData (string sql, Func projector) { using(SqlConnection _conn = new SqlConnection(@”Data Source=…”)) { using(SqlCommand _cmd = new SqlCommand(sql, _conn)) { _conn.Open(); _cmd.CommandTimeout = 100000; using(IDataReader rdr = _cmd.ExecuteReader()) { while (rdr.Read()) yield return projector(rdr); } } […]