C# 设置方法的最大运行时间

C# 设置方法的最大运行时间,c#,multithreading,task,C#,Multithreading,Task,如果我有一个方法,我想执行一些(潜在的)长时间运行的函数,并且我想限制它的执行时间,那么我一直在使用这种模式(请原谅代码中的任何错误,手动键入的,而不是IDE中的,这是对更大代码的简化) 如果我想在异步容量中使用GetHello方法,即public async Task GetHello(),我将如何做到这一点,同时希望保留类似的模式?我有以下内容,但是我收到了关于的编译器警告,该异步方法缺少'await'运算符,将按预期同步运行 public async Task<string>

如果我有一个方法,我想执行一些(潜在的)长时间运行的函数,并且我想限制它的执行时间,那么我一直在使用这种模式(请原谅代码中的任何错误,手动键入的,而不是IDE中的,这是对更大代码的简化)

如果我想在异步容量中使用
GetHello
方法,即
public async Task GetHello()
,我将如何做到这一点,同时希望保留类似的模式?我有以下内容,但是我收到了关于
的编译器警告,该异步方法缺少'await'运算符,将按预期同步运行

public async Task<string> GetHello()
{
    var task = Task.Run(async () => 
    {
        // await something long running
        return "Hello";
    });

    bool success = task.Wait(TimeSpan.FromMilliseconds(1000));

    if (success)
    {
        return task.Result;
    }
    else
    {
        throw new TimeoutException("Timed out.");
    }
}
公共异步任务GetHello() { var task=task.Run(异步()=> { //等待一些长时间的事情 回复“你好”; }); bool success=task.Wait(TimeSpan.frommillistics(1000)); 如果(成功) { 返回任务。结果; } 其他的 { 抛出新的TimeoutException(“超时”); } }

我只是不知道如何更改此项,也不知道将wait放在何处,以使其按预期工作。

您可以使用
CancellationToken
和waitable
任务组合使用。如果要实现所需行为:

public async Task<string> GetHello()
{
    var task = Task.Run(async () => 
    {
        // await something long running
        return "Hello";
    });

    bool success = task.Wait(TimeSpan.FromMilliseconds(1000));

    if (success)
    {
        return task.Result;
    }
    else
    {
        throw new TimeoutException("Timed out.");
    }
}
public async Task<string> GetHello()
{
    var cts = new CancellationTokenSource();
    var task = Task.Run(async () =>
    {
        // await something long running and pass/use cts.Token here too
        return "Hello";
    }, cts.Token);

    var delay = Task.Delay(1000, cts.Token);

    var finishedFirst = await Task.WhenAny(task, delay);
    cts.Cancel();
    if (finishedFirst == task)
    {
        return task.Result;
    }
    else
    {
        throw new TimeoutException("Timed out.");
    }
} 
公共异步任务GetHello() { var cts=新的CancellationTokenSource(); var task=task.Run(异步()=> { //等待长时间运行的东西,并在此处传递/使用cts.Token 回复“你好”; },cts.Token); var delay=任务延迟(1000,cts.Token); var finishedFirst=等待任务。WhenAny(任务,延迟); cts.Cancel(); 如果(finishedFirst==任务) { 返回任务。结果; } 其他的 { 抛出新的TimeoutException(“超时”); } }
您可以添加一个
CancellationTokenSource
。阅读文档::CancellationTokenSource(Int32)初始化CancellationTokenSource类的一个新实例,该实例将在指定的延迟(毫秒)后被取消。我知道CancellationTokenSource是如何工作的-这与回答我的问题有何关系?正如我提到的,Guru Stron实现了
CancellationTokenSource
。这就是为什么
TimeoutException
不一定会阻止
任务继续运行。这就是你的想法吗?@Barns向我指出文档并没有提供答案,但还是要谢谢你。可能更重要的是,异步方法会检查令牌,如果它被取消,就会中止。否则,长时间运行的工作可能在超时异常出现后仍会运行很长时间,因此在
else
块中添加
cts.Cancel()
?@joelc不在
else
块中,将其添加到
等待长时间运行的内容