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