我有一个方法,有时需要一分钟多的时间才能执行。我想创建一个任务来监视执行此方法所需的时间。如果该方法在 2 分钟内执行,我应该返回第一个任务的输出,否则我应该抛出异常。我使用 .net Framework 4.0,以 C# 作为语言。
我无法使用Microsoft Reactive Extensions在这种情况下,因为它释放了主线程。 在发生以下情况之前我不想释放主线程
- 超时
- 数据已返回
- 发生任何其他异常
请提出您的建议。
最佳答案
理想情况下,您应该使用带有超时的 CancellationTokenSource
并在方法中观察其 CancellationToken
。如果这不可能,您可以使用 Task.WhenAny
。以下 MethodAsync
实现应该适合您的 .NET 4.0 场景:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
// the method to monitor and timeout
int Method()
{
Thread.Sleep(3000); // sleep for 3s
return 42;
}
Task<int> MethodAsync(int timeout)
{
// start the Method task
var task1 = Task.Run(() => Method());
// start the timeout task
var task2 = Task.Delay(timeout);
// either task1 or task2
return Task.WhenAny(task1, task2).ContinueWith((task) =>
{
if (task.Result == task1)
return task1.Result;
throw new TaskCanceledException();
});
}
// The entry of the console app
static void Main(string[] args)
{
try
{
// timeout in 6s
int result = new Program().MethodAsync(6000).Result;
Console.WriteLine("Result: " + result);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
Console.WriteLine("Hit enter to exit.");
Console.ReadLine();
}
}
}
下面是使用async/await
的MethodAsync
版本,如果你可以使用Microsoft.Bcl.Async :
async Task<int> MethodAsync(int timeout)
{
// start the Method task
var task1 = Task.Run(() => Method());
// start the timeout task
var task2 = Task.Delay(timeout);
// either task1 or task2
var task = await TaskEx.WhenAny(task1, task2);
if (task == task1)
return task1.Result;
throw new TaskCanceledException();
}
关于c# - 在 C# .net 中创建两个任务并在特定时间段后关闭其中一个任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21185399/