温馨提示×

c#异步开发如何处理超时

c#
小樊
81
2024-10-18 21:48:57
栏目: 编程语言

在C#中,处理异步操作的超时可以采用以下方法:

  1. 使用Task.WhenAnyTask.WhenAll方法:

Task.WhenAny方法允许你在一组任务中等待任何一个任务完成。这对于超时处理非常有用。你可以创建一个CancellationTokenSource,并将其传递给Task.WhenAny方法。如果在指定的超时时间内没有任务完成,你可以取消任务并处理超时。

示例:

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        cts.CancelAfter(TimeSpan.FromSeconds(3)); // 设置超时时间为3秒

        var task1 = FetchDataAsync("https://api.example.com/data1", cts.Token);
        var task2 = FetchDataAsync("https://api.example.com/data2", cts.Token);

        await Task.WhenAny(task1, task2);

        if (cts.IsCancellationRequested)
        {
            Console.WriteLine("请求超时");
        }
        else
        {
            var result = await task1; // 或者 await task2,取决于哪个任务先完成
            Console.WriteLine("请求成功: " + result);
        }
    }

    static async Task<string> FetchDataAsync(string url, CancellationToken cancellationToken)
    {
        using (HttpClient client = new HttpClient())
        {
            try
            {
                HttpResponseMessage response = await client.GetAsync(url, cancellationToken);
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
            catch (HttpRequestException e)
            {
                if (e.Message.Contains("请求超时"))
                {
                    throw; // 重新抛出异常,让调用者处理
                }
                else
                {
                    throw new Exception("获取数据时发生错误", e);
                }
            }
        }
    }
}
  1. 使用Task.RunCancellationToken

你还可以使用Task.Run方法创建一个异步任务,并在其中使用CancellationToken来处理超时。这种方法类似于第一种方法,但将任务提交给Task.Run

示例:

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        cts.CancelAfter(TimeSpan.FromSeconds(3)); // 设置超时时间为3秒

        var result = await Task.Run(() => FetchDataAsync("https://api.example.com/data", cts.Token), cts.Token);

        if (cts.IsCancellationRequested)
        {
            Console.WriteLine("请求超时");
        }
        else
        {
            Console.WriteLine("请求成功: " + result);
        }
    }

    static async Task<string> FetchDataAsync(string url, CancellationToken cancellationToken)
    {
        using (HttpClient client = new HttpClient())
        {
            try
            {
                HttpResponseMessage response = await client.GetAsync(url, cancellationToken);
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
            catch (HttpRequestException e)
            {
                if (e.Message.Contains("请求超时"))
                {
                    throw; // 重新抛出异常,让调用者处理
                }
                else
                {
                    throw new Exception("获取数据时发生错误", e);
                }
            }
        }
    }
}

这两种方法都可以用于处理C#异步开发中的超时问题。你可以根据具体需求选择合适的方法。

0