Tag: async await

取消HttpClient请求 – 为什么TaskCanceledException.CancellationToken.IsCancellationRequested为false?

给出以下代码: var cts = new CancellationTokenSource(); try { // get a “hot” task var task = new HttpClient().GetAsync(“http://www.google.com”, cts.Token); // request cancellation cts.Cancel(); await task; // pass: Assert.Fail(“expected TaskCanceledException to be thrown”); } catch (TaskCanceledException ex) { // pass: Assert.IsTrue(cts.Token.IsCancellationRequested, “expected cancellation requested on original token”); // fail: Assert.IsTrue(ex.CancellationToken.IsCancellationRequested, “expected cancellation requested on token attached […]

异步等待性能?

(只是一个理论问题 – 对于非gui应用程序) 假设我有很多awaits代码: public async Task ConsumeAsync() { await A(); await b(); await c(); await d(); //.. } 每项任务可能需要很短的时间, 问题 (再次,理论上的) 可能存在这样一种情况: 整个时间处理所有那些“释放回线程”和“取回线程”(红色和绿色在这里:) 花费更多的时间比单个线程可以完成所有工作并且有少量延迟, 我的意思是,我想成为最富有成效的,但是,因为所有这些来回切换 – 我实际上失去了生产力。 这种情况会发生吗?

具有异步lambda和Task.WaitAll的Task.Factory.StartNew

我正在尝试在任务列表中使用Task.WaitAll 。 事情是任务是一个异步lambda,它打破Tasks.WaitAll因为它永远不会等待。 这是一个示例代码块: List tasks = new List(); tasks.Add(Task.Factory.StartNew(async () => { using (dbContext = new DatabaseContext()) { var records = await dbContext.Where(r => r.Id = 100).ToListAsync(); //do long cpu process here… } } Task.WaitAll(tasks); //do more stuff here 这不会因为异步lambda而等待。 那我该如何等待我的lambda中的I / O操作呢?

了解C#5 async / await中的上下文

我是否正确async / await本身与并发/并行无关,只不过是继续传递样式(CPS)实现? 真正的线程是由await传递/恢复的SynchronizationContext实例执行的? 如果这是正确的,我有关于SynchronizationContext的以下问题: 它保证在同一个线程上执行延续。 但是,是否有任何保证线程的上下文信息是持久的? 我的意思是Name , CurrentPrincipal , CurrentCulture , CurrentUICulture等。它依赖于框架(ASP.NET,WinForms,WCF,WPF)吗?

返回Task的接口的同步实现

类似于在同步代码中实现需要Task返回类型的接口,虽然我很好奇我是否应该忽略编译器错误,而是我的情况生成。 假设我有这样的界面: public interface IAmAwesome { Task MakeAwesomeAsync(); } 在某些实现中,使用async和await async完成可以带来很多好处。 这实际上是接口试图允许的内容。 在其他情况下,也许很少见,只需要一个简单的同步方法来制作真棒。 所以让我们假设实现如下: public class SimplyAwesome : IAmAwesome { public async Task MakeAwesomeAsync() { // Some really awesome stuff here… } } 这有效,但编译器警告: 这种方法缺少’await’运算符并将同步运行。 考虑使用await运算符等待非阻塞API调用,或者’await TaskEx.Run(…)’在后台线程上执行CPU绑定工作。 编译器实际上是在建议这个解决方案: public class SimplyAwesome : IAmAwesome { public async Task MakeAwesomeAsync() { await Task.Run(() => { // Some […]

等待基于任务的队列

我想知道是否存在ConcurrentQueue的实现/包装器,类似于BlockingCollection ,其中从集合中获取不会阻塞,而是异步并且将导致异步等待直到将项放入队列中。 我已经提出了自己的实现,但它似乎没有按预期执行。 我想知道我是否正在重塑已经存在的东西。 这是我的实现: public class MessageQueue { ConcurrentQueue queue = new ConcurrentQueue(); ConcurrentQueue<TaskCompletionSource> waitingQueue = new ConcurrentQueue<TaskCompletionSource>(); object queueSyncLock = new object(); public void Enqueue(T item) { queue.Enqueue(item); ProcessQueues(); } public async Task Dequeue() { TaskCompletionSource tcs = new TaskCompletionSource(); waitingQueue.Enqueue(tcs); ProcessQueues(); return tcs.Task.IsCompleted ? tcs.Task.Result : await tcs.Task; } private void ProcessQueues() […]

在异步方法中返回和等待任务之间的区别

以下方法之间有什么区别吗? 一个比另一个好吗? public static async Task SendAsync1(string to, string subject, string htmlBody) { // … await smtp.SendMailAsync(message); // No return statement } public static Task SendAsync2(string to, string subject, string htmlBody) { // … return smtp.SendMailAsync(message); } 这个方法将从MVC控制器方法调用; 例如: public async Task RegisterUser(RegisterViewModel model) { // … await Mailer.SendAsync(user.Email, subject, body); return View(model); }

AspNetSynchronizationContext并等待ASP.NET中的延续

在异步ASP.NET Web API控制器方法中await后,我注意到一个意外的(我会说,一个冗余的)线程切换。 例如,下面我希望在#2和3#位置看到相同的ManagedThreadId ,但最常见的是我在#3处看到了不同的线程: public class TestController : ApiController { public async Task GetData() { Debug.WriteLine(new { where = “1) before await”, thread = Thread.CurrentThread.ManagedThreadId, context = SynchronizationContext.Current }); await Task.Delay(100).ContinueWith(t => { Debug.WriteLine(new { where = “2) inside ContinueWith”, thread = Thread.CurrentThread.ManagedThreadId, context = SynchronizationContext.Current }); }, TaskContinuationOptions.ExecuteSynchronously); //.ConfigureAwait(false); Debug.WriteLine(new { where = […]

在WinForms上使用async / await访问Task.Run中的UI控件

我在WinForms应用程序中有以下代码,只有一个按钮和一个标签: using System; using System.IO; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private async void button1_Click(object sender, EventArgs e) { await Run(); } private async Task Run() { await Task.Run(async () => { await File.AppendText(“temp.dat”).WriteAsync(“a”); label1.Text = “test”; }); } } } 这是我正在处理的实际应用程序的简化版本。 […]

为什么从Async CTP / Release中删除“SwitchTo”?

我今天尝试使用SwitchTo方法切换到GUI线程,并发现我解除它的示例不起作用,只是因为该方法不存在。 然后我在这里发现了这个模糊: 我们摆脱它的原因是因为它太危险了。 另一种方法是在TaskEx.Run中捆绑你的代码…… 我的问题很简单:它为什么危险? 使用它会带来哪些特定危险? 请注意,我确实阅读了该帖的其余部分,因此我确实理解这里存在技术限制。 我的问题仍然是,如果我意识到这一点,为什么它很危险 ? 我正在考虑重新实现帮助方法来给我指定的function,但是如果有一些根本上被破坏的东西,除了有人认为它是危险的,我不会这样做。 具体来说,非常天真,这是我如何考虑实现所需的方法: public static class ContextSwitcher { public static ThreadPoolContextSwitcher SwitchToThreadPool() { return new ThreadPoolContextSwitcher(); } public static SynchronizationContextSwitcher SwitchTo(this SynchronizationContext synchronizationContext) { return new SynchronizationContextSwitcher(synchronizationContext); } } public class SynchronizationContextSwitcher : INotifyCompletion { private readonly SynchronizationContext _SynchronizationContext; public SynchronizationContextSwitcher(SynchronizationContext synchronizationContext) { _SynchronizationContext = synchronizationContext; } […]