为了账号安全,请及时绑定邮箱和手机立即绑定

取消客户端上长时间运行的操作 cancel

取消客户端上长时间运行的操作 cancel

C#
临摹微笑 2023-08-20 10:05:44
我使用 ASP.NET Core 和 Razor Pages 开始了我的第一个项目。根据客户端请求,将启动长时间运行的数据库操作。现在我想认识到,当用户离开网站时,可以取消数据库操作。我已经尝试过使用cancelToken,但它永远不会被取消。public async Task<JsonResult> OnPostReadAsync([DataSourceRequest] DataSourceRequest request, CancellationToken cancellationToken){    var messages = await _logMessageService.GetLogMessagesAsync(request, cancellationToken);    return new JsonResult(messages.ToDataSourceResult(request));}该函数由 Telerik Kendo UI 网格调用。你能告诉我,为什么取消令牌没有被取消,或者我还有什么其他选项来检测客户端的堕胎?编辑1我将令牌传递给 NpgsqlCommand 的此函数调用:var dataReader = await command.ExecuteReaderAsync(cancellationToken);
查看完整描述

2 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

要取消 IO 绑定(即运行时间较长的任务),您可以执行以下代码,这些代码是我从 C# with CLR 书中获得的。


设计任务的扩展方法如下。


private static async Task<TResult> WithCancellation<TResult>(this Task<TResult> originalTask,

CancellationToken ct) {

   // Create a Task that completes when the CancellationToken is canceled

   var cancelTask = new TaskCompletionSource<Void>();

   // When the CancellationToken is canceled, complete the Task

  using (ct.Register(

     t => ((TaskCompletionSource<Void>)t).TrySetResult(new Void()), cancelTask)) {

    // Create a Task that completes when either the original or

    // CancellationToken Task completes

    Task any = await Task.WhenAny(originalTask, cancelTask.Task);

    // If any Task completes due to CancellationToken, throw OperationCanceledException

     if (any == cancelTask.Task) ct.ThrowIfCancellationRequested();

  }

  // await original task (synchronously); if it failed, awaiting it

  // throws 1st inner exception instead of AggregateException

 return await originalTask;

}

如下面的示例代码所示,您可以使用上面设计的扩展方法来取消它。


public static async Task Go() {

   // Create a CancellationTokenSource that cancels itself after # milliseconds

   var cts = new CancellationTokenSource(5000); // To cancel sooner, call cts.Cancel()

   var ct = cts.Token;

   try {

    // I used Task.Delay for testing; replace this with another method that returns a Task

     await Task.Delay(10000).WithCancellation(ct);

     Console.WriteLine("Task completed");

   }

   catch (OperationCanceledException) {

    Console.WriteLine("Task cancelled");

  }

}

在此示例中,取消是根据给定时间完成的,但您可以通过调用 cancel 方法来调用取消。


查看完整回答
反对 回复 2023-08-20
?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

该问题是 IISExpress 中的错误,

我切换到 Kestrel,现在一切都按预期进行。


查看完整回答
反对 回复 2023-08-20
  • 2 回答
  • 0 关注
  • 152 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信