说我有两个场景:
1)WebApi控制器
[System.Web.Http.HttpPost]
[System.Web.Http.AllowAnonymous]
[Route("api/registerMobile")]
public async Task<HttpResponseMessage> RegisterMobile(RegisterModel model)
{
var registerResponse = await AuthUtilities.RegisterUserAsync(model, _userService, User);
if (registerResponse.Success) {
var response = await _userService.GetAuthViewModelAsync(model.Username, User);
return Request.CreateResponse(HttpStatusCode.OK, new ApiResponseDto() { Success = true, Data = response });
}
else {
return Request.CreateResponse(HttpStatusCode.OK, registerResponse);
}
}
Run Code Online (Sandbox Code Playgroud)
2)MVC控制器
[Route("public")]
public async Task<ActionResult> Public()
{
if (User.Identity.IsAuthenticated)
{
var model = await _userService.GetAuthViewModelAsync(User.Identity.Name);
return View("~/Views/Home/Index.cshtml", model);
}
else
{
var model = await _userService.GetAuthViewModelAsync(null);
return View("~/Views/Home/Index.cshtml", model);
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在阅读我应该使用的时间ConfigureAwait …
我正在尝试在测试中使用带有异步方法的reactiveui测试调度程序.
等待异步调用时,测试挂起.
根本原因似乎是异步方法中等待的命令.
[Fact]
public async Task Test()
=> await new TestScheduler().With(async scheduler =>
{
await SomeAsyncMethod();
// *** execution never gets here
Debugger.Break();
});
private async Task SomeAsyncMethod()
{
var command = ReactiveCommand.CreateFromTask(async () =>
{
await Task.Delay(100);
});
// *** this hangs
await command.Execute();
}
Run Code Online (Sandbox Code Playgroud)
如何与没有死锁的测试调度程序一起执行异步调用?
我正在使用reactiveui 9.4.1
编辑:
我已经尝试了WithAsync()Funks答案中建议的方法,但行为是一样的.
我是ASP.NET Core和C#的新手,一般来自Java世界,我对async/await关键字如何工作有点困惑:本文解释了如果一个方法被标记为异步,则意味着
"此方法包含涉及等待异步操作的控制流,因此将由编译器重写为连续传递样式,以确保异步操作可以在正确的位置恢复此方法." 异步方法的重点在于它当前线程尽可能多
所以我认为在异步方法和在字节码/虚拟机级别上实现的同一线程上运行的调用者之间传递控制是一种非常酷的方式.我的意思是我期望下面的代码
public static void Main(string[] args)
{
int delay = 10;
var task = doSthAsync(delay);
System.Console.WriteLine("main 1: " + Thread.CurrentThread.ManagedThreadId);
// some synchronous processing longer than delay:
Thread.Sleep(2 * delay)
System.Console.WriteLine("main 2: " + Thread.CurrentThread.ManagedThreadId);
task.Wait();
}
public static async Task<String> doSthAsync(int delay)
{
System.Console.WriteLine("async 1: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(delay);
System.Console.WriteLine("async 2: " + Thread.CurrentThread.ManagedThreadId);
return "done";
}
Run Code Online (Sandbox Code Playgroud)
会写的
async 1: 1 main 1: 1 main 2: 1 async 2: 1 …
据我所知,AspNetCore没有 SynchronizationContext.
“重新进入”请求上下文涉及许多内务任务,例如设置 HttpContext.Current 和当前线程的身份和文化。
所以我创建了一个简单的 .Net Core Api 项目,并执行以下操作:
[HttpGet]
[Route("checkVar")]
public async Task<IActionResult> checkVar()
{
Thread.SetData(Thread.GetNamedDataSlot("Random"),4);
await Task.Delay(1000);
var res = Thread.GetData(Thread.GetNamedDataSlot("Random"));
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,res它的价值为4. 我很惊讶,因为我相信这SetData是同步上下文的一部分。(在asp.net core中不应该存在)
更多,当我使用时ConfigureAwait(false),我进入null了res。
所以现在我很困惑。因为ConfigureAwait 在asp.net core中不应该有影响
题:
如果 asp.net core 没有 SynchronizationContext,那么为什么在4之后可用await?为什么会ConfigureAwait在非 SynchronizationContext 环境中改变结果?
我有一个MVC应用程序,我覆盖我的基本控制器的OnActionExecuting()方法来设置我的线程文化:
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
var langCode = GetLangCode();
Thread.CurrentThread.CurrentUICulture = new CultureInfo(langCode);
Thread.CurrentThread.CurrentCulture = new CultureInfo(langCode);
}
Run Code Online (Sandbox Code Playgroud)
当我开始异步编程时,如果我们将我们修改过的文化返回到线程池,并且在异步任务完成时调度新线程,我很好奇文化是如何持久化的?我应该知道的任何陷阱?
尽管这个问题有很多结果,但没有一个真正给我一个明确的答案。
每次我尝试通过 AddAsync 和 SaveChangesAsync 方法插入错误数据(例如重复的主键)时,我都会看到此日志:执行 DbCommand 失败(15 毫秒)
我还看到 SQL PROFILER 上的错误,很明显这是主键冲突。在这些情况下 SaveChangesAsync 不会抛出任何错误!它只是无限期挂起,导致内存泄漏,最终应用程序崩溃。我尝试用 try catch 包装 savechanges 无济于事,甚至添加了一个取消令牌以在 2 秒后自动取消,即使这样也没有停止挂起。结果总是一个永不结束的 HTTP 请求,它永远不会向客户端返回响应。*我还尝试在没有配置等待的情况下运行 savechangesasync,结果是一样的。
用于上下文和存储库的 DI:
services.AddDbContext<SalesDBContext>(o =>
o.UseSqlServer(appSettings.ConnectionString)
.EnableDetailedErrors(true)
.EnableSensitiveDataLogging()
, ServiceLifetime.Scoped);
services.AddScoped<IRepository, EfRepository>();
Run Code Online (Sandbox Code Playgroud)
控制器方法:
[HttpPost]
public async Task<IActionResult> Post([FromBody] SomeRequest request)
{
if (ModelState.IsValid)
{
var data = await _service.AddAsync(request);
return Ok(data);
}
return BadRequest(ModelState.Values);
}
Run Code Online (Sandbox Code Playgroud)
addasync 是调用者:
public class EfRepository : IRepository
{
private readonly SalesDBContext _dbContext;
public EfRepository(SalesDBContext dbContext)
{
_dbContext = dbContext;
}
public …Run Code Online (Sandbox Code Playgroud) 我有一个 .NET CORE 2 后端。在我的一个控制器端点中,我正在创建要通过电子邮件发送的邀请。这似乎是端点上的一个巨大瓶颈,考虑之后,我真的不需要等待这些邀请。如果电子邮件未能发送出去,我无论如何也无能为力。
如果我不这样做await sendFn(),它本质上会是一种即发即忘的方法吗?我正在阅读另一个 stackoverflow 线程,我必须这样做sendFn().ContinueWith(t => throw(t))才能捕获异常,因为它将在另一个线程中。
我在代码库周围有类似的邮件功能。他们每个人做的事情都略有不同,但是有没有我可以做的服务来包装这些东西,让它们着火而忘记?我认为有些地方我不能使用await(如果有效的话),但有些东西会改变数据库上下文,所以如果我不等待它们,我可能会遇到某些东西正在访问相同的数据库上下文的情况。
[HttpPost]
public async Task<IActionResult> CreateEvent([FromBody] Event val)
{
_ctx.Event.Add(val);
await _ctx.SaveChangesAsync();
await SendInvitations(val); // fn in question
return Ok();
}
public async Task SendInvitation(Event event)
{
forEach (var person in event.people)
{
await _ctx.Invitation.Add(person); // This shouldn't happen while another iteration or some other async code elsewhere is using the db ctx.
_ctx.SaveChangesAsync();
await _mailService.SendMail(person.email,"you have been invited"); // don't really need …Run Code Online (Sandbox Code Playgroud) 我正在检查一些使用 .NET 4.7.2 的 ASP.NET Web API 代码。
这是一个示例控制器和操作方法:
public class ThingController : System.Web.Http.ApiController
{
// ...
public async Task<IHttpActionResult> GetValue()
{
var value = await _db.GetValue().ConfigureAwait(false);
return Content(value);
}
}
Run Code Online (Sandbox Code Playgroud)
我读到,最佳实践是不在ConfigureAwait应用程序代码中使用,以便继续执行捕获的同步上下文,因为可能存在与捕获的上下文关联的所需状态。然而,一般来说,我们应该使用ConfigureAwait(false)这样的方法,这样我们就不会不必要地继续捕获的同步上下文。
所以我的想法是,我们不想ConfigureAwait(false)在此 Web API 代码中的任何位置进行调用。
然后我读到了有关死锁的内容,并且在使用 ASP.NET Core 时这并不重要(尽管我不是)。
我添加了一个断点并检查了SynchronizationContext.Current哪个是null.
ConfigureAwait(false)我可以安全地删除该项目的所有调用吗?如果不是,在什么情况下应该保留这些调用?
c# ×7
async-await ×5
.net ×2
asp.net-core ×2
asp.net-mvc ×2
asynchronous ×2
.net-5 ×1
reactiveui ×1