在生活在岩石下2年就业明智的,我现在面临着Blazor在我的新工作场所,并有很多赶上做后,主要是做ASP .netframeworkmvc之前的2年。
尝试自己在Blazor服务器端,我试图应用我过去的知识,其中包括异步操作的cancellationtoken,我找不到太多的信息,他们结合Blazor。
它们仍然是最佳实践还是在某个时候过时了?我确实发现了this previously asked question,它建议在OnInitializedAsync()
方法上创建一个tokensource,并在Dispose()
上取消它,老实说,我觉得有点粗糙。(我需要在每个页面上实现这个,你知道...干)
我还找到了this Article about advanced Scenarios on Microsoft Docs,它解释了如何实现电路处理程序,老实说,这有点超出了我现在的能力范围,很可能超出了我的小家庭项目的范围。
相比之下,在asp.net框架MVC中,我会构建一个如下所示的控制器:
namespace SampleWebsite.Controllers
{
public class SampleController : ApiController
{
private readonly MyEntities _entities = new MyEntities();
public async Task<IHttpActionResult> MyAsyncApi(CancellationToken cancellationToken)
{
var result = _entities.MyModel.FirstOrDefault(e => e.Id == 1, cancellationToken: cancellationToken);
return OK(result);
}
}
}
CancellationToken将由asp.net Framework / Core注入,并直接链接到当前上下文连接管道。因此,如果用户关闭连接,令牌将变为无效。
我本以为对于asp.net core和blazor来说,依赖注入是其中很大的一部分,这里也是如此,但是我在这里找不到任何关于这方面的文档。
那么,在这一点上,cancellationtoken是否应该继续使用,或者微软是否在后台为异步任务做了一些魔术?如果是的话,最好的实现是什么?
**EDIT:**以下是我得设置,以便澄清:
Blazor组件:
@page "/Index"
@inject IIndexService Service
@* Some fancy UI stuff *@
@code {
private IEnumerable<FancyUiValue> _uiValues;
protected override async Task OnInitializedAsync()
{
_uiValues = await Service.FetchCostlyValues();
}
}
注入式服务级别执行繁重得工作:
public interface IIndexService
{
Task<IEnumerable<FancyUiValue>> FetchCostlyValues();
}
public class IndexService : IIndexService
{
public async Task<IEnumerable<FancyUiValue>> FetchCostlyValues()
{
var uiValues = await heavyTask.ToListAsync(); // <-- Best way to get a cancellationtoken here?
return uiValues;
}
}
我的问题是,在代码的特定部分获得令牌的最佳方式是什么,或者它是无关紧要的,因为服务器会在连接(例如)结束时杀死所有正在运行的任务?
2条答案
按热度按时间brgchamk1#
在使用Blazor两年之后,我发现将
CancellationToken
传递给更长生命周期的对象(例如Singleton或Scoped Service)中的任务的唯一可靠方法是IDisposeable
和CancellationTokenSource
的组合在重复使用或仅为了遵守DRY规则时,您也可以从
ComponentBase
类继承,然后将该类用于需要传递CancellationToken
的组件:第一次
我还发现,虽然您可以注入
IHttpContextAccessor
并使用HttpContext.RequestAborted
标记(与ASP.NET MVC方法调用中生成和注入的标记相同),但从当前的.Net6
版本开始,它永远不会触发,即使与客户端的连接被切断,并且提供的HttpContext
被释放。这可能是Github上的开发团队的一个案例,因为我确实看到了它的用例,其中用户被允许退出组件,而任务继续进行,直到用户完全离开网站。
(For在这种情况下,我建议的解决方法是编写您自己的
CircuitHandler
,它将为您提供删除电路时的事件。)k97glaaz2#
您可以创建一个公开
CancellationToken
的基本组件,并在项目的所有组件中自动使用此基本组件,而不是手动将CancellationTokenSource
添加到所有组件实现应用程序组件库
然后将
@inherits ApplicationComponentBase
添加到_Imports.razor
文件高翔听差一叫:
然后尝试导航到另一个页面,您调用的任务将被取消