我想使用Response.OnStarting
执行一些利用异步等待模式的代码。 Response.OnStarting
方法定义为
public void OnStarting(Func<Task> callback)
我经常看到它用来通过如下代码修改标头:
context.Response.OnStarting( () => {
//modify the headers or do some synchronous work
});
但是我需要从OnStarting委托中进行一些异步工作。假设执行异步工作的方法声明如下:
public Task DoWorkAsync() {
//write to a db or do something else async
return Task.CompletedTask;
}
使用以下方法通过OnStarting委托调用此方法是否有效?
context.Response.OnStarting(async () => {
await DoWorkAsync();
});
在Visual Studio中,它可以编译而不会发出警告,并且似乎可以正常工作。但是,对我来说,Response.OnStarting
方法可用于进行同步和异步调用似乎很奇怪。有时,异步等待世界仍然让我有些挠头。您能否阐明这种方法是否有效以及为什么?为什么Response.OnStarting
可以与同步和异步匿名方法一起使用(如果可以的话)?
更新
我做了一些挖掘,看是否可以找到调用委托传递给OnStarting
方法的调用的代码。
我发现,DefaultHttpRespose
对象包含OnStarting
方法,并且在该方法内部它基本上称为IHttpResponseFeature.OnStarting
,请参见此处:
public override void OnStarting(Func<object, Task> callback, object state)
{
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
HttpResponseFeature.OnStarting(callback, state);
}
但是有趣的是,我唯一能找到IHttpResponseFeature.OnStarting
实现的地方是here,其代码如下:
void IHttpResponseFeature.OnStarting(Func<object, Task> callback, object state)
{
var register = Prop<Action<Action<object>, object>>(OwinConstants.CommonKeys.OnSendingHeaders);
if (register == null)
{
throw new NotSupportedException(OwinConstants.CommonKeys.OnSendingHeaders);
}
// Need to block on the callback since we can't change the OWIN signature to be async
register(s => callback(s).GetAwaiter().GetResult(), state);
}
但是该实现在异步委托调用上受阻。甚至对此有评论,但我不明白为什么这样做是必要的?而且我不确定这是IHttpResponseFeature.OnStarting
的实现正在运行,这只是我在github上可以找到的唯一实现。任何帮助,不胜感激。
答案 0 :(得分:2)
但是对我来说,Response.OnStarting方法可用于进行同步和异步调用都显得很奇怪。
必须同步实现 同步API。 Func<int>
必须返回int
;它不能返回Task<int>
。
异步API可以异步实现或。 Func<Task<int>>
可能具有异步实现,返回的Task<int>
将在将来完成。或者它可能具有同步实现,返回一个已经用Task<int>
值完成的int
。
在处理异步API(包括接口和委托签名)时,完全允许同步实现。
我不会因阻塞实现而分心。该注释表明OWIN在应该是异步API的地方有一个同步API,而IHttpResponseFeature.OnStarting
只是在向您隐藏这种怪异。