c# - 在 C# .net 中创建两个任务并在特定时间段后关闭其中一个任务

标签 c# .net multithreading task-parallel-library thread-synchronization

我有一个方法,有时需要一分钟多的时间才能执行。我想创建一个任务来监视执行此方法所需的时间。如果该方法在 2 分钟内执行,我应该返回第一个任务的输出,否则我应该抛出异常。我使用 .net Framework 4.0,以 C# 作为语言。

我无法使用Microsoft Reactive Extensions在这种情况下,因为它释放了主线程。 在发生以下情况之前我不想释放主线程

  1. 超时
  2. 数据已返回
  3. 发生任何其他异常

请提出您的建议。

最佳答案

理想情况下,您应该使用带有超时的 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/awaitMethodAsync版本,如果你可以使用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/

相关文章:

c# - 谷歌图表和 asp.net MVC

c# - 更改查询字符串内容编辑或从 Web 配置文件拆分(QUERY_STRING 服务器变量)

c# - ContentStringFormat 绑定(bind)不会在 propertychange 上刷新

c# - 在 WPF 中,如何在 WindowsFormsHost 上画一条线?

c# - C# 中的简单套接字服务器在尝试向客户端写入数据时意外关闭连接

c# - IIS服务器找不到index.aspx文件-404错误

.net - 如何减少网络上运行的 .Net dll 数量

multithreading - 子进程与父进程共享资源吗?

c++ - 将 _beginthread 返回的 uintptr_t 转换为 HANDLE 是否安全?

使用 Semaphore 运行时出现 java.util.NoSuchElementException