您好,我重新创建了我在工作项目中遇到的问题。
//КЛАСС Startup.cs
public async void Configure(IApplicationBuilder app, IHostingEnvironment env, IDataAccessService dataAccessService)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
try
{
await dataAccessService.LongInvoke();
var disp = dataAccessService.IsDispose; // !!!! true
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
app.UseMvc();
}
//РЕГИСТРАЦИЯ сервиса
builder.RegisterType<DataAccessService>()
.As<IDataAccessService>()
.InstancePerLifetimeScope();
//СЕРВИС
public class DataAccessService : IDataAccessService, IDisposable
{
public bool IsDispose { get; set; }
public async Task LongInvoke()
{
await Task.Delay(10000);
var calc = 5000 + 500;
}
public void Dispose()
{
IsDispose = true;
}
}
如果在注入服务的Configure
类方法中执行操作,则内部调用 dataAccessService 将比操作完成更快(标志 disp == true)。在调用 后立即 ,即 当一个线程返回到线程池时,它会立即被调用。Startup.cs
LongInvoke
Dispose
await Task.Delay(10000)
LongInvoke
Dispose()
LongInvoke
但是如果你这样做
dataAccessService.LongInvoke().GetAwaiter().GetResult();
然后一切正常,我不明白其中的区别,请解释。
事实是该方法
Configure
返回void
,即调用代码不知道您在该方法内部进行了一些异步操作。调用代码有什么作用?它准备好方法所需的所有实体,调用方法,等待它完成,然后杀死你的
IDisposable
. 但是当你使用一个单词时await
,方法的同步部分就结束了,那一刻调用代码认为整个方法已经结束,并杀死你的IDisposable
,虽然实际上方法继续工作,但已经异步(即,该方法将在异步操作后恢复工作,即使调用代码已经结束)。当你像这样调用你的操作时
dataAccessService.LongInvoke().GetAwaiter().GetResult();
,它会阻塞线程直到操作完成,所以它不是异步调用。并且,由于你的代码变成了同步的(代码中没有操作符await
,代码中没有异步调用),调用代码会等待方法结束,Dispose
一切都结束后再调用。