Tag: 异步 等待

应该弃用Task.Wait吗?

我学到了从池线程调用Task.Wait会导致线程饥饿死锁的困难方法。 根据这篇MSDN文章 ,在“死锁”一章中,我们应遵守这两条规则: 不要创建任何同步方法等待异步函数的类,因为可以从池中的线程调用此类。 如果类阻塞等待异步函数,则不要在异步函数内使用任何类。 似乎唯一合法使用Task.Wait的地方是主要function – 我在这里夸大了一点,但你明白了。 为什么Task.Wait仍然是.NET框架的一部分,看它有多危险?

使用await Task.Delay进行杀戮性能

假设我想开始大致每秒分配N个任务。 所以我尝试了这个: public async Task Generate(int numberOfCallsPerSecond) { var delay = TimeSpan.FromMiliseconds(1000/numberOfCallsPerSecond); // a call should happen every 1000 / numberOfCallsPerSecond miliseconds for (int i=0; i < numberOfcallsPerSecond; i++) { Task t = Call(); // don't wait for result here await Task.Delay(delay); } } 起初我预计这将在1秒内运行,但对于numberOfCallsPerSecond = 100 ,我的12核CPU需要16 seconds 。 似乎等待Task.Delay增加了很多开销(当然没有它就可以在3ms内生成调用。 在这种情况下,我没想到await会增加很多开销。 这是正常的吗? 编辑: 请忘记Call()。 […]

何时是使用Task.Result而不是等待任务的最佳位置

虽然我已经在.NET中使用异步代码一段时间了,但我最近才开始研究它并了解正在发生的事情。 我刚刚经历了我的代码并试图改变它,所以如果一项任务可以与某些工作并行完成,那么它就是。 例如: var user = await _userRepo.GetByUsername(User.Identity.Name); //Some minor work that doesn’t rely on the user object user = await _userRepo.UpdateLastAccessed(user, DateTime.Now); return user; 现在变成: var userTask = _userRepo.GetByUsername(User.Identity.Name); //Some work that doesn’t rely on the user object user = await _userRepo.UpdateLastAccessed(userTask.Result, DateTime.Now); return user; 我的理解是现在正在从数据库中获取用户对象WHILST正在进行一些不相关的工作。 但是,我看到的post暗示结果应该很少使用,等待是首选但我不明白为什么我要等待我的用户对象被提取,如果我可以执行一些其他独立的逻辑同时?

在控制台应用程序中使用async / await时,为什么需要AsyncContext?

我在我的控制台应用程序中调用异步方法。 我不希望应用程序在启动后立即退出,即在等待完成任务之前。 好像我可以这样做: internal static void Main(string[] args) { try { Task.WaitAll(DoThisAsync()); } catch (Exception ex) { Console.Error.WriteLine(ex); throw; } } internal static async Task DoThisAsync() { //… } 但根据Stephen Cleary的文章 ,似乎我不能这样做,而应该创建某种上下文,让async在完成后返回(例如AsyncContext )。 上面的代码可以工作,它在Task.WaitAll(DoThisAsync());之后返回主线程Task.WaitAll(DoThisAsync()); ,那么为什么我需要使用自定义上下文?

如何在不关闭流的情况下取消NetworkStream.ReadAsync

我试图使用NetworkStream.ReadAsync()来读取数据,但我无法找到如何在调用时取消ReadAsync()。 对于后台,NetworkStream由连接的BluetoothClient对象(来自32Feet.NET蓝牙库)提供给我。 我正在尝试的当前get-it-working代码如下。 int bytesRead; while (this.continueReading) { bytesRead = await this.stream.ReadAsync(this.buffer, 0, (int)this.buffer.Length); Console.WriteLine(“Received {0} bytes”, bytesRead); } Console.WriteLine(“Receive loop has ended”); 代码可以很好地接收数据,并且如果continueReading标志设置为false并且接收到数据,则将停止循环,但是在接收到数据之前,它将不会继续通过ReadAsync()行。 我无法看到如何在不接收数据的情况下中止呼叫。 我知道ReadAsync有一个重载提供了一个CancellationToken,但是由于NetworkStream没有覆盖默认的ReadAsync行为,所以会忽略该令牌(请参阅带有取消令牌的NetworkStream.ReadAsync永远不会取消 )。 我试过关闭底层流,这导致等待ReadAsync调用抛出ObjectDisposedException,底层蓝牙连接也被关闭。 理想情况下,我不想完全切断与设备的连接只是为了停止阅读。 它似乎不是一种干净的方式,并且感觉不必拆除整个流只是为了中断va ReadAsync()调用。 任何建议?

“异步一路走下去”:嗯,底部到底是什么?

我正在努力完全理解async – await ,我的理解中的一个async是看到什么是“一直向下”。 我创建了一个async方法,它被另一个async方法等调用,一直到我理解的模糊术语,如“一个UI”或“一个可以处理多个请求的Web服务器”。 我如何用技术术语描述什么是“一直向下”? 让我们来看一个Web服务器的第二个例子。 假设我有一个控制器动作 [HttpGet] public async Task GetRecords() { var records = await repository.GetRecordsFromDbAsync(); return Ok(records); } 我在哪里可以找到.NET源代码中的“一路向下”代码,它可以异步调用它?

我怎么能等待取消订阅后在Rx可观察序列中完成所有操作?

介绍 在我的WPF C#.NET应用程序中,我使用反应式扩展(Rx)来订阅事件,我经常需要从数据库重新加载一些内容来获取更新UI所需的值,因为事件对象通常只包含ID和一些元数据。 我使用Rx调度在后台加载数据并更新调度程序上的UI。 我在Rx序列中混合“Task.Run”时遇到了一些不好的经验(当使用“SelectMany”时,不再保证顺序,并且很难控制UnitTests中的调度)。 另请参阅: 在反应流水线中执行TPL代码并通过测试调度程序控制执行 我的问题 如果我关闭我的应用程序(或关闭选项卡)我想取消订阅然后等待DB调用(从Rx“Select”调用)仍然可以在“subscription.Dispose”之后运行。 到目前为止,我还没有找到任何好的实用工具或简单方法。 问题 是否有任何框架支持等待仍在Rx链中运行的所有内容 ? 如果没有,你有什么好主意如何使一个易于使用的实用程序? 是否有任何好的替代方法来实现同样的目标? 例 public async Task AwaitEverythingInARxChain() { // In real life this is a hot observable event sequence which never completes IObservable eventSource = Enumerable.Range(1, int.MaxValue).ToObservable(); IDisposable subscription = eventSource // Load data in the background .ObserveOn(Scheduler.Default) .Select(id => LoadFromDatabase(id)) // […]

如何在没有Async CTP的情况下实现等待

您将如何实现与Async CTP await关键字类似的function? 是否存在一个简单的实现,在所有情况下都像await一样,或者是否需要针对不同场景的不同实现?

是否可以在自定义WCF服务行为中创建TransactionScope? (async,await,TransactionScopeAsyncFlowOption.Enabled)

TL; DR? 截屏解释问题: https : //youtu.be/B-Q3T5KpiYk 问题 将事务从客户端流向服务时Transaction.Current在等待服务调用服务后变为null 。 当然,除非您在服务方法中创建一个新的TransactionScope,如下所示: [OperationBehavior(TransactionScopeRequired = true)] public async Task CallAsync() { using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await _service.WriteAsync(); await _service.WriteAsync(); scope.Complete(); } } 为什么默认情况下不启用TransactionScopeAsyncFlowOption我不知道,但我不想重复自己,所以我想我总是使用自定义行为创建一个带有该选项的内部事务管理器。 问题更新 它甚至不必是服务调用服务,等待本地异步方法也使Transaction.Current无效。 用一个例子来澄清 [OperationBehavior(TransactionScopeRequired = true)] public async Task CallAsync() { await WriteAsync(); // Transaction.Current is now null await WriteAsync(); } 试图解决方案 […]

纤维与异步等待

我正在加入一个C#项目,其中开发人员大量使用Fibers 。 在这个项目之前,我甚至没有听说过它们,之前使用async await和Threads和BackgroundWorker来处理我的多任务操作。 今天我问他们为什么他们使用Fiber s,主要的开发人员说他更容易调试。 这意味着他知道特定函数来自哪个线程,甚至可以访问堆栈中更高的变量。 我想知道使用Fiber s与使用新的async await和使用Thread的优点和缺点是什么。 PS:我们正在使用.Net 4.5