有人可以向我解释一下Task.Wait(CancellationToken)重载的用法吗?MSDN确实说了很多......
这就是我通常处理任务取消的方式:
        var source = new CancellationTokenSource();
        var task = Task.Factory.StartNew(() => 
        {
            while (true)
            {
                source.Token.ThrowIfCancellationRequested();
            }
        }, source.Token);
        try
        {
            task.Wait();
        }
        catch (AggregateException exc)
        {
            exc.Flatten().Handle(e => e is OperationCanceledException);
        }
那么什么时候将令牌传递给Wait方法有用呢?
给定CancellationToken,我想在取消CancellationToken时对代表异步操作的对象调用'cancel'方法.这可能吗?
背景:我正在通过以下方式(或多或少)与代表异步操作的API进行交互:
class AsyncOp
{
    void Start(Action callback);//returns 'immediately', while beginning an async op. Callback is called when the operation completes.
    void Cancel();//aborts async operation and calls callback
}
我可以Task DoAsyncOp()很容易地将它包装在一个方法中,但我想支持取消,例如Task DoAsyncOp(CancellationToken cancellationToken).在我的情况下,取消CancellationToken时,在AsyncOp对象上调用Cancel.
在Azure Service Bus队列客户端中,我使用该ReceiveBatchAsync方法等待指定的时间异步接收一批消息.
var messages = await queueClient.ReceiveBatchAsync(10, TimeSpan.FromSeconds(30));
我想彻底关闭我的应用程序,所以我正在实现CancellationToken所有长期运行的异步进程,但似乎没有可以ReceiveBatchAsync取消的重载.
换句话说,我想这样做,但我不能:
var messages = await queueClient.ReceiveBatchAsync(10, TimeSpan.FromSeconds(30),
                                                       cancellationToken);
将这样CancellationToken的任务应用于不直接提供的任务的最佳方法是什么?我不想在关机期间等待整整30秒.
是否有任何机制为单元测试提供 CancellationToken (或者像 [TestInitialize] 这样的属性),可以用来理解单元测试被取消?我找不到。
.net c# unit-testing task-parallel-library cancellation-token
我正在尝试将HttpClient调用的默认超时设置为5秒.
我通过这样做了CancellationTokenSource.
这是相关的代码:
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(TimeSpan.FromSeconds(5));
var result = _httpClient.SendAsync(request, cancellationToken.Token);
按照调用代码获取"任务被取消"错误(我在.NET 4.7控制台应用程序中测试)的预期工作,但我注意到在Fiddler中请求仍然运行1分钟,直到它最终放弃:
有人可以解释这种行为吗?
我希望在触发取消时基础请求也会被取消.
_httpClient 实例化如下: new HttpClient { BaseAddress = baseAddress }
我知道有Timeout设置,但不确定我是否应该使用它或取消令牌?我的猜测是Timeout针对非异步/等待的情况?
c# cancellationtokensource dotnet-httpclient cancellation-token
有没有人知道CancellationToken的功能,如果您在中添加了一个参数,例如
public static UpdateResult UpdateMany<TDocument>(
    this IMongoCollection<TDocument> collection,
    Expression<Func<TDocument, bool>> filter,
    UpdateDefinition<TDocument> update,
    UpdateOptions options = null,
    CancellationToken cancellationToken = null
)
是回滚吗?或它是做什么的?
考虑以下两种通过 处理取消的方法CancellationToken:
public async Task DoAllAvailableWork(CancellationToken cancelToken)
{
    foreach (var job in GetAllAvailableWork())
    {
        await job.Process();
        if (cancelToken.IsCancellationRequested())
            return;
    }
}
public async Task DoAllAvailableWork(CancellationToken cancelToken)
{
    foreach (var job in GetAllAvailableWork())
    {
        await job.Process();
        cancelToken.ThrowIfCancellationRequested();
    }
}
在这种情况下job.Process(),正在执行一些原子工作,一旦开始就不应该或无法停止,因此它不接受CancellationToken.
是否有任何理由更喜欢其中一种方法而不是另一种?如果是,应该首选哪种方法?
检查IsCancellationRequested()和返回对我来说感觉更干净,因为抛出意味着出了问题,而取消是我们明确计划处理的情况(这就是我们接受的原因CancellationToken)。另一方面,调用者不一定知道我们将采取哪种方法,因此无论OperationCancelledException我们选择哪个选项,他们都必须设置一个 try/catch。
我发现自己经常编写这样的代码:
try
{
    cancellationTokenSource.Cancel();
    await task.ConfigureAwait(false); // this is the task that was cancelled
}
catch(OperationCanceledException)
{
    // Cancellation expected and requested
}
鉴于我请求取消,这是预料之中的,而且我真的希望忽略该异常。这似乎是一个常见的案例。
有没有更简洁的方法来做到这一点?我是否错过了有关取消的信息?看来应该有什么task.CancellationExpected()方法什么的。
我经常看到以下代码,第一个视图看起来不错,因为它用于在执行其他操作之前检查先决条件。
但是当人们读到方法的名称时,感觉前面的 if 语句已经包含在方法本身中了。那么是否有任何理由像本示例中那样编写代码,或者可以跳过 if 语句并ThrowIfCancellationRequested直接运行。
当然,如果需要在退出之前进行清理,那就是另一回事了,那么我完全理解 if 语句的用法。
if (cancellationToken.IsCancellationRequested)
{
    cancellationToken.ThrowIfCancellationRequested();
}
根据Scalability in ASP.NET Web APIs with Cancellation Tokens,CancellationTokens 应该仅用于 HTTP GET 请求:
\n\n\n可能产生副作用的请求(例如创建、更新或删除数据)也应该保持原样,因为如果请求在错误的时刻中断,则存在损害系统数据完整性的真正风险,尤其是在该操作有多个内部步骤。这使得我们只剩下无效请求,即那些只获取数据但在完成后不修改任何内容的请求,尽管指标和日志也一样。换句话说,如果实现正确,HTTP GET 请求。
\n
Andrew Lock 在他的博客文章《在 ASP.NET Core MVC 控制器中使用 CancellationTokens》中也持有相同的观点:
\n\n\n如果请求修改状态,那么您可能不希望在方法中途停止执行。另一方面,如果请求没有副作用,那么您可能希望尽快停止(可能很昂贵)操作。
\n
另一方面,根据在 .NET Core Web API 中使用 CancellationToken,鼓励将 CancellationToken 也传递给 POST / PUT / DELETE 请求:
\n\n\n其优点有很多,其中包括在创建、更新或删除时避免重复记录。
\n
我记得在我过去使用过的几个 .NET Web 应用程序中,CancellationToken 作为参数传递给控制器中 GET / POST / PUT / DELETE 请求的所有操作。
\n上述两个来源中谁是正确的。采用哪种最佳实践?就个人而言,我认为一旦创建/更新/删除数据涉及超过 1 个数据库表/1 个文件/等,向 POST、PUT 和 DELETE …
c# ×10
async-await ×3
task ×3
cancellation ×2
.net ×1
asp.net-core ×1
azure ×1
unit-testing ×1