【发布时间】:2020-10-11 11:01:37
【问题描述】:
在工作两年后,我现在在我的新工作场所遇到了 Blazor,并且在 2 年之前主要从事 ASP.NET Framework MVC 之后,我还有很多工作要做。
在 Blazor 服务器端尝试自己,我尝试应用我过去的知识,其中包括用于异步操作的取消令牌,但我找不到与 Blazor 结合使用的有关它们的太多信息。
它们仍然是最佳实践还是在某个时候已经过时?
我确实找到了this previously asked question,它建议在OnInitializedAsync() 方法上创建一个tokensource,并在Dispose() 上取消它,老实说我觉得有点粗糙。
(我需要为每个页面实现这个,你知道...... DRY)
我还找到了this Article about advanced Scenarios on Microsoft Docs,它解释了如何实现电路处理程序,老实说,现在这有点超出我的能力,而且很可能超出了我的小型家庭项目的范围。
相比之下,在 asp.net Framework 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,这里也是这种情况,但我在这里找不到任何关于此的文档。
那么,此时是否仍应使用取消令牌,或者微软是否在后台为异步任务做了一些魔术?如果是,最好的实施方式是什么?
编辑: 这是我要澄清的设置:
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;
}
}
我的问题是,在代码的特定部分获取令牌的最佳方法是什么,或者它是否无关紧要,因为服务器会在连接(例如)结束时终止所有正在运行的任务?
【问题讨论】:
-
您的编辑有帮助,但您仍然没有异常处理。你想对错误做什么?还是超时?
-
@HenkHolterman:问题是关于在 Blazor 中取消异步任务的最佳实践,而不是异常处理。我不太熟悉 Blazor 的双向二进制通信,我的艰难过程围绕“如果用户启动昂贵的异步任务(例如:生成 PDF 报告)然后导航到另一个页面怎么办?”。根据我的 MVC 知识,异步任务将继续运行并消耗资源,然后返回并被父线程上的控制器忽略或发送到客户端并被客户端拒绝。
-
是的,对于这样的工作 (PDF),我会使用 CancelSrc。和处置()。但通常你会使用服务端点。
标签: c# asp.net .net-core async-await blazor