Tag: 异步 等待

为什么不抛出这个exception?

我有时会使用一组任务,为了确保它们都在等待我使用这种方法: public async Task ReleaseAsync(params Task[] TaskArray) { var tasks = new HashSet(TaskArray); while (tasks.Any()) tasks.Remove(await Task.WhenAny(tasks)); } 然后像这样调用它: await ReleaseAsync(task1, task2, task3); //or await ReleaseAsync(tasks.ToArray()); 但是,最近我注意到了一些奇怪的行为,并设置了ReleaseAsync方法是否存在问题。 我设法将它缩小到这个简单的演示,如果你包含System.Threading.Tasks它在linqpad中运行。 它也可以在控制台应用程序或asp.net mvc控制器中稍作修改。 async void Main() { Task[] TaskArray = new Task[]{run()}; var tasks = new HashSet(TaskArray); while (tasks.Any()) tasks.Remove(await Task.WhenAny(tasks)); } public async Task run() { return […]

异步并等待For循环

我有一个Windows服务,根据计划运行各种作业。 确定要运行的作业后,会将一个计划对象列表发送到迭代列表并运行每个作业的方法。 问题是由于外部数据库调用,某些作业最多可能需要10分钟才能运行。 我的目标是没有一个工作阻止其他队列,基本上一次有多个运行。 我认为使用async和await可以解决这个问题,但我以前从未使用过这些。 现行代码: public static bool Load(List scheduleList) { foreach (Schedule schedule in scheduleList) { Load(schedule.ScheduleId); } return true; } public static bool Load(int scheduleId) { // make database and other external resource calls // some jobs run for up to 10 minutes return true; } 我尝试更新到这段代码: public async static Task LoadAsync(List […]

C#中基于任务的异步方法的超时模式

据我所知,有两种可能的模式来实现基于任务的异步方法的超时: 内置超时 public Task DoStuffAsync(TimeSpan timeout) 这种方法难以实现,因为实现整个调用堆栈的全局超时并不容易。 例如,Web API控制器接收HTTP请求并调用DoStuffAsync ,调用者希望全局超时为3秒。 也就是说,每个内部异步方法调用都需要接收已经使用过的时间的减法… 没有内置超时 public Task DoStuffAsync(CancellationToken cancellationToken) ………. CancellationTokenSource cancellationSource = new CancellationTokenSource(); Task timeoutTask = Task.Delay(3000); if(await Task.WhenAny(DoStuffAsync(cancellationTokenSource), timeoutTask) == timeoutTask) { cancellationSource.Cancel(); throw new TimeoutException(); } 这似乎是最可靠和易于实现的模式。 第一个调用者定义全局超时,如果超时 ,则将取消所有挂起的操作。 此外,它为直接调用者提供取消令牌,内部调用将共享相同的取消令牌引用。 因此,如果最高调用者超时,它将能够取消任何工作线程。 整个问题 有没有我缺少的模式,或者如果我使用no内置超时开发API,我是否正确?

由非托管应用程序托管的托管组件中的Await和SynchronizationContext

[EDITED] 这似乎是 Framework的Application.DoEvents实现中的一个错误 ,我在这里报告过 。 在UI线程上恢复错误的同步上下文可能会严重影响像我这样的组件开发人员。 赏金的目标是更多地关注这个问题并奖励@MattSmith,他的答案帮助追踪它。 我负责通过COM互操作将基于.NET WinForms UserControl的组件作为ActiveX暴露给传统的非托管应用程序 。 运行时要求是.NET 4.0 + Microsoft.Bcl.Async。 该组件被实例化并在应用程序的主要STA UI线程上使用。 它的实现使用async/await ,因此它期望在当前线程(即WindowsFormsSynchronizationContext )上安装序列化同步上下文的实例。 通常, WindowsFormsSynchronizationContext由Application.Run设置,这是托管应用程序的消息循环运行的地方。 当然, 这不是非托管主机应用程序的情况 ,我无法控制它。 当然,主机应用程序仍然有自己的经典Windows消息循环,因此序列化await延续回调应该不是问题。 然而,到目前为止我提出的解决方案都不是完美的,甚至都不能正常工作。 这是一个人为的例子,主机app调用Test方法: Task testTask; public void Test() { this.testTask = TestAsync(); } async Task TestAsync() { Debug.Print(“thread before await: {0}”, Thread.CurrentThread.ManagedThreadId); var ctx1 = SynchronizationContext.Current; Debug.Print(“ctx1: {0}”, ctx1 != […]

什么是异步和等待,何时在Windows开发中使用这些?

我总是看到Silverlight中使用的关键字async,但是想知道是否有人对虚拟对象的解释是什么以及何时使用它及其好处。 如果你能解释,请大家好评。 谢谢。

使用.net 4.5中的Async API对串口通信代码进行示例?

有人能指出我使用.net 4.5异步API(异步,等待,任务,ReadAsync等)进行串行通信的工作示例吗? 我试图调整现有的事件驱动的串行样本,并得到各种可怕的行为 – “其他应用程序正在使用的端口”错误,VS2013调试器抛出exception和锁定 – 这通常需要PC重启才能从中恢复。 编辑 我从头开始编写自己的样本。 这是一个简单的Winforms项目,它写入Output窗口。 表单上的三个按钮 – 打开端口,关闭端口和读取数据。 ReadDataAsync方法调用SerialPort.BaseStream.ReadAsync。 截至目前,它将从端口读取数据,但我遇到了问题,使其变得强大。 例如,如果我拔下串行电缆,打开端口,然后单击Read Data两次,我将得到一个System.IO.IOException(我有点期待),但我的应用程序停止响应。 更糟糕的是,当我尝试停止我的程序时,VS2013会抛出一个“正在进行停止调试”对话框,该对话框永远不会完成,我甚至无法从任务管理器中杀死VS. 每次发生这种情况都必须重启我的电脑。 不好。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private SerialPort _serialPort; public Form1() […]

名为Mutex等待

因此我不能使用async线程仿射锁 – 如何在运行多个进程时保护我的资源? 例如,我有两个使用以下任务的进程: public async Task MutexWithAsync() { using (Mutex myMutex = new Mutex(false, “My mutex Name”)) { try { myMutex.WaitOne(); await DoSomething(); return true; } catch { return false; } finally { myMutex.ReleaseMutex(); } } } 如果由Mutex保护的moethod是同步的,那么上面的代码将起作用但是async我会得到: 从不同步的代码块调用对象同步方法。 那么命名Mutex对异步代码没用吗?

在后台操作过程中显示模态UI并继续

我有一个运行后台任务的WPF应用程序,它使用async/await 。 任务是在进展时更新应用程序的状态UI。 在此过程中,如果满足某个条件,我需要显示一个模态窗口,让用户知道这样的事件,然后继续处理,现在也更新该模态窗口的状态UI。 这是我想要实现的草图版本: async Task AsyncWork(int n, CancellationToken token) { // prepare the modal UI window var modalUI = new Window(); modalUI.Width = 300; modalUI.Height = 200; modalUI.Content = new TextBox(); using (var client = new HttpClient()) { // main loop for (var i = 0; i < n; i++) { token.ThrowIfCancellationRequested(); // […]

在没有等待#2的情况下调用异步方法

我有一个异步方法: public async Task ValidateRequestAsync(string userName, string password) { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.GetAsync(url); string stringResponse = await response.Content.ReadAsStringAsync(); return bool.Parse(stringResponse); } } 我这样称呼这个方法: bool isValid = await ValidateRequestAsync(“user1”, “pass1”); 我可以使用同步方法调用相同的方法,而不使用await关键字吗? 例如: public bool ValidateRequest(string userName, string password) { return ValidateRequestAsync(userName, password).Result; } 我认为这会导致僵局。 编辑 调用上面的方法会使调用永远不会结束。 (该方法不再到达终点)

什么线程在`await`关键字后运行代码?

我先发一个简单的例子: private void MyMethod() { Task task = MyAsyncMethod(); task.Wait(); } private async Task MyAsyncMethod() { //Code before await await MyOtherAsyncMethod(); //Code after await } 假设我在单线程应用程序中运行上述代码,就像控制台应用程序一样。 我很难理解代码//Code after await的代码是如何运行的。 据我所知,当我在MyAsyncMethod()控件中点击await关键字时,会返回到MyMethod() ,但后来我用task.Wait()锁定了该线程。 如果线程被锁定,那么如果应该接受它的线程被锁定,那么//Code after await运行//Code after await怎么办? 是否创建了一个新线程来//Code after await ? 或者主线程是否神奇地走出task.Wait()运行//Code after await ? 我不确定这是怎么回事?