一段时间后如何取消功能?

时间:2016-09-15 12:16:07

标签: c# cancellationtokensource cancellation-token

我想知道如何在一段时间后取消功能!

例如,如何取消此功能?

private async Task function()
    {
        try
        {
            while (true)
            {
                //mycode
            }
        }
        catch{ }
    }

4 个答案:

答案 0 :(得分:2)

前段时间我遇到了同样的问题,找到了一个很好的解决方案。我通过wcf以这种方式将异步调用分离到另一个服务(请参阅下面的代码),在最长时间之后做两件事取消:

您可以将CancellationToken与第二个任务结合使用,以与您正在运行的任务并行运行,并在必要时取消它:

    private const int TimeOut = 50000;

    public static async Task<T> HandleServiceCall<T>(Func<Task<T>> doServiceCall, CancellationTokenSource source) where T : class
    {
        var delaySource = new CancellationTokenSource(TimeSpan.FromSeconds(50));
        source.Token.ThrowIfCancellationRequested();

        var res = doServiceCall();

        if (await Task.WhenAny(res, Task.Delay(TimeSpan.FromMilliseconds(TimeOut), delaySource.Token)) == res)
        {
            delaySource.Cancel();
            await res;
        }
        else
        {
            source.Cancel();
            throw new Exception("Your Text");
        }

        return await res;
    }

您可以通过以下方式调用此方法:

    var source = new CancellationTokenSource(TimeSpan.FromSeconds(50));
    source.Token.ThrowIfCancellationRequested();
    MyWrapperClass.HandleServiceCall(async () => await MyAsyncMethod(source.Token), source).Result

澄清这里做了什么: 我正在使用给定的最大TimeSpan为我的任务创建一个取消令牌,然后将此令牌提供给应该调用的异步方法。 这个调用作为func提供给我的HandleServiceCall方法。 此方法将创建另一个具有更大TimeSpan的CancellationToken,它将作为延迟任务运行(task.Delay将等待直到触发令牌)。 Task.WhenAny将查看正常的异步任务或延迟的任务是否先完成。如果是延迟时间,则您的最长时间已过期,并且会抛出异常。

问候 康斯坦丁

答案 1 :(得分:2)

  

如何取消此功能?

通常情况下,等待处理的方法需要CancellationToken,因此您只需将其传递给:

private async Task functionAsync(CancellationToken cancellationToken)
{
  while (true)
  {
    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); //mycode
  }
}

答案 2 :(得分:1)

您可以使用Timer类,在需要时启动它(可能是程序的开头),并使用一些简单的if语句来停止它,例如*如果timer大于设置的时间,结束程序。 *

答案 3 :(得分:1)

我添加小例子

  static CancellationTokenSource cts;
    static  void Main(string[] args)
    {
        cts = new CancellationTokenSource();
       Task.Factory.StartNew(test);
       cts.Cancel();
    }

    private async static void test()
    {

        await function(cts.Token);

    }

    static async Task function(CancellationToken ct)
    {
        try
        {
            while (!ct.IsCancellationRequested)
            {
                Thread.Sleep(1000);

                //mycode
            }
        }
        catch { }
    }