如何取消正在等待超时的任务而不抛出异常

发布于 2024-11-19 15:39:23 字数 541 浏览 4 评论 0原文

使用取消标记取消超时(超时结束之前)的任务时,会引发异常。示例:

mytask.start();
bool didTaskRunInTime = mytask.wait(5 mins, _cancelToken);

这意味着我不能像下面这样继续下去。

//was the task cancelled
if (_cancelToken.IsCancelRequested)
{
    // log cancel from user to file etc
}

if (didTaskRunInTime )
{
    int taskResult = myTask.Result;
    // log result to file
}
else if (!_cancelToken.IsCancelRequested)
{
    // Tell user task timed out , log a message etc
}

我必须在 catch 块中完成所有这些操作,并且我的代码看起来很混乱。这样做的正确方法是什么?

When canceling a task that has a timeout (before the timeout has ended) using a cancel token an exception is thrown. Example:

mytask.start();
bool didTaskRunInTime = mytask.wait(5 mins, _cancelToken);

Which means I cannot go on like below.

//was the task cancelled
if (_cancelToken.IsCancelRequested)
{
    // log cancel from user to file etc
}

if (didTaskRunInTime )
{
    int taskResult = myTask.Result;
    // log result to file
}
else if (!_cancelToken.IsCancelRequested)
{
    // Tell user task timed out , log a message etc
}

I will have to do all this in my catch block and my code is looking messy. What is the correct way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

栖竹 2024-11-26 15:39:23

您可以使用 Task.WaitAny 调用只是该任务的数组。然后,您可以根据任务的状态采取行动,但方法会返回。示例代码:

using System;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        Task sleeper = Task.Factory.StartNew(() => Thread.Sleep(100000));

        int index = Task.WaitAny(new[] { sleeper },
                                 TimeSpan.FromSeconds(0.5));
        Console.WriteLine(index); // Prints -1, timeout

        var cts = new CancellationTokenSource();

        // Just a simple wait of getting a cancellable task
        Task cancellable = sleeper.ContinueWith(ignored => {}, cts.Token);

        // It doesn't matter that we cancel before the wait
        cts.Cancel();

        index = Task.WaitAny(new[] { cancellable },
                             TimeSpan.FromSeconds(0.5));
        Console.WriteLine(index); // 0 - task 0  has completed (ish :)
        Console.WriteLine(cancellable.Status); // Cancelled
    }
}

请注意,如果任务出错,您应该“观察”异常,以避免它在最终确定时发生爆炸:)

You could call Task.WaitAny with an array of just that task. Then you can act on the status of the task, however the method returns. Sample code:

using System;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        Task sleeper = Task.Factory.StartNew(() => Thread.Sleep(100000));

        int index = Task.WaitAny(new[] { sleeper },
                                 TimeSpan.FromSeconds(0.5));
        Console.WriteLine(index); // Prints -1, timeout

        var cts = new CancellationTokenSource();

        // Just a simple wait of getting a cancellable task
        Task cancellable = sleeper.ContinueWith(ignored => {}, cts.Token);

        // It doesn't matter that we cancel before the wait
        cts.Cancel();

        index = Task.WaitAny(new[] { cancellable },
                             TimeSpan.FromSeconds(0.5));
        Console.WriteLine(index); // 0 - task 0  has completed (ish :)
        Console.WriteLine(cancellable.Status); // Cancelled
    }
}

Note that if the task is faulted, you should "observe" the exception in order to avoid it going bang when it's finalized :)

无人接听 2024-11-26 15:39:23

尝试使用OperationCanceledException

try
{           
    mytask.start();
    bool didTaskRunInTime = mytask.wait(5 mins, _cancelToken);

    if (didTaskRunInTime )
    {
        int taskResult = myTask.Result;
        //log result to file
    }
    else
    {
        // Tell user task timed out , log a message etc
    }
}
catch (OperationCanceledException ex)
{
    // log cancel from user to file et
}

try to use OperationCanceledException

try
{           
    mytask.start();
    bool didTaskRunInTime = mytask.wait(5 mins, _cancelToken);

    if (didTaskRunInTime )
    {
        int taskResult = myTask.Result;
        //log result to file
    }
    else
    {
        // Tell user task timed out , log a message etc
    }
}
catch (OperationCanceledException ex)
{
    // log cancel from user to file et
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文