Tag: async await

到Task.Run或不运行Task.Run

假设我有一个包含异步方法的接口,我有两个不同的接口实现。 两种实现中的一种是自然异步,而另一种则不是。 实现非异步方法的“最正确”方法是什么? public interface ISomething { Task DoSomethingAsync(); } // Normal async implementation public class Implementation1 : ISomething { async Task ISomething.DoSomethingAsync() { return await DoSomethingElseAsync(); } } // Non-async implementation public class Implementation2 : ISomething { // Should it be: async Task ISomething.DoSomethingAsync() { return await Task.Run(() => DoSomethingElse()); } // Or: async […]

以线程或任务方式启动异步方法

我是C#的新手, await/async ,目前正在玩一下。 在我的场景中,我有一个简单的客户端对象,它具有WebRequest属性。 客户端应该通过WebRequest的RequestStream定期发送alive-messages。 这是client-object的构造函数: public Client() { _webRequest = WebRequest.Create(“some url”); _webRequest.Method = “POST”; IsRunning = true; // –> how to start the ‘async’ method (see below) } 和async alive-sender方法 private async void SendAliveMessageAsync() { const string keepAliveMessage = “{\”message\”: {\”type\”: \”keepalive\”}}”; var seconds = 0; while (IsRunning) { if (seconds % 10 […]

并发执行异步方法

使用async / await模型,我有一个方法,它对Web服务进行3次不同的调用,然后返回结果的并集。 var result1 = await myService.GetData(source1); var result2 = await myService.GetData(source2); var result3 = await myService.GetData(source3); allResults = Union(result1, result2, result3); 使用典型等待,这3个调用将彼此同步执行。 我将如何让它们同时执行并在完成后加入结果?

对等待的模拟对象的异步回调

我试图模拟unit testing的复杂情况: _mockController = new Mock(); _mockController.Setup(tc => tc.Interrupt(It.IsAny<Func>())) .Callback<Func>(async f => await f.Invoke()); IController有一个void方法Interrupt(Func> f) ,它将一些工作排​​队。 我正在测试的对象会调用Interrupt() ,我可以像这样validation调用: _mockController.Verify(tc => tc.Interrupt(It.IsAny<Func>()), Times.Once); …但是当在回调中调用参数Func ,在Task不遵守await关键字:在Task完成之前继续执行测试(尽管在回调中await )。 其中一个症状是在Interrupt() Task参数中添加await Task.Delay(1000)会将通过的测试转换为失败的测试。 这种行为是由于测试期间如何处理线程或Task的细微差别? 或Moq的限制? 我的测试方法有这个签名: [Test] public async Task Test_Name() { }

在Identity Framework的方法中,HttpContext.Current为null

我正在使用ASP.NET MVC 5和Identity Framework。 当我在ApplicationDbContext()上调用UserManager.UpdateAsync(…)时,我的事件处理程序将运行SaveChanges。 这里我使用HttpContext.Current用于不同的目的(日志记录和审计)所以我必须说当前用户。 但是整个方法在一个工作线程中运行,这里HttpContext.Current为null。 UserManager的“同步”方法最大的问题只是异步版本的包装,因此调用是序列化的,但方法(和事件处理程序)仍然在不同的工作线程中运行。 请注意,此问题与async / await上下文无关。 在await之后的控制器中(或调用’sync’版本)我已经返回正确的HttpContext,即使控制器的方法在另一个线程中继续。 没关系。 所以问题出在异步工作者中,它将同时在“同步”和异步版本中运行。 我想我理解这种现象(但我对假’同步’方法版本不满意,真正的同步方法不会出现这个问题。)我只是不知道如何处理/解决它。 [btw:将UserManager的操作实现为简单的纯同步版本,然后用异步multithreading包装器包装它们不是更自然吗? 如果我们继续这种异步方式而不考虑我们将很快发明异步赋值运算符。 它花了我几十个小时(只是这个问题),全球成本高达数十亿美元,我相信在很多情况下,它的回报低于它的价格。 额外奖励:我们所说的UserManager的影响非常小,但相同的原则和问题可以应用任何开箱即用的库(黑盒子),作者没有实现同步版本,或者不关心控制器线程的上下文。 那么EF,它不是那么边缘……那么DI容器实例化基础设施如“请求范围”或“会话范围”呢? 如果在没有HttpContext.Current的线程中进行解析,他们肯定会行为不端。 最近我刷新了SendGrid NuGet,并且(作为一个突破性的变化)Deliver()方法消失了,现在只有DeliverAsync()存在… 我想有一个安全可靠的方法,如何访问此worker中的HttpContext以进行日志记录和审计。 示例代码,控制器’sync’版本: [AcceptVerbs(HttpVerbs.Post)] public virtual ActionResult Edit(ApplicationUser user) { // validation etc // Update() seems to be only a poor wrapper around the async version, still uses a worker thread. var result […]

async / await和IDisposable接口

我有一个实现IDisposable接口的类来处理私有变量_MailMessage同一个类有一个异步方法,它使用私有IDisposable变量,即async public Task Send我的问题是:正常的IDisposable实现是否会配置异步方法完成后的私有变量? 这是我正在谈论的课程的一个例子: public class Email : IEmail { private readonly IEmailData _EmailData; private MailMessage _MailMessage = new MailMessage(); public Email(IEmailData emailData) { if (emailData == null) { throw new ArgumentNullException(“emailData”); } if (String.IsNullOrEmpty(emailData.To)) { throw new ArgumentNullException(“emailData.To”); } if (String.IsNullOrEmpty(emailData.From)) { throw new ArgumentNullException(“emailData.From”); } if (String.IsNullOrEmpty(emailData.FromName)) { throw new ArgumentNullException(“emailData.FromName”); } […]

如何在SignalR客户端中使用async / await与hub.On

我有一个与SignalR Hub(服务器)通信的.Net Windows服务(客户端)。 大多数客户端方法都需要时间来完成。 当从服务器接收调用时,我如何(或者我需要)包装目标方法/ hub.On以避免警告: “因为没有等待这个调用,所以当前方法的执行在调用完成之前继续。考虑将await运算符应用于调用的结果” 在客户端上,这是启动/设置代码的示例: IHubProxy _hub string hubUrl = @”http://localhost/”; var connection = new HubConnection(hubUrl, hubParams); _hub = connection.CreateHubProxy(“MyHub”); await connection.Start(); _hub.On(“SendMessageToClient”, i => OnMessageFromServer(i.Id, i.Message)); _hub.On(“SendCommandToClient”, i => OnCommandFromServer(i.Id, i.Command)); 同样在客户端上,这是方法的示例: public static async Task OnMessageFromServer(string Id, string message) { try { var result = await processMessage(message); //long running task […]

检查Action是否为异步lambda

因为我可以将Action定义为 Action a = async () => { }; 我可以以某种方式确定(在运行时)动作是否异步?

调试.NET异步/等待函数时无法检查变量

我有一个使用async/awaitfunction的.NET 4.5项目。 当我尝试在await语句后检查/快速监视变量引用时,我得到以下内容: The name ‘id’ does not exist in the current context 知道如何修复这个我可以调试吗? 编辑 – 这是代码 [Fact] public async Task works_as_expected() { var repo = Config.Ioc.GetInstance<IAsyncRepository>(); var work = Config.Ioc.GetInstance(); Customer c= new Customer() { FirstName = “__Micah”, LastName = “__Smith_test”, DateCreated = DateTime.Now, DateModified = DateTime.Now, Email = “m@m.com”, Phone = “7245551212” }; […]

什么时候你真的需要在Web框架上异步?

Async已成为.net中的流行语,MS已在Web API 2中引入它,以便可以处理更多请求,而其他请求则等待IO完成。 虽然我可以看到它的好处,但这真的是一个问题吗? x64架构在线程池中有30000多个线程,所以除非你的网站上有那么多并发用户真的需要异步? 即使你有那么多没有缓存的并发用户,我也很确定SQL Server会因为那么多请求而崩溃? 除了它是否真的需要在Web框架上进行异步路由时才会shiny?