优秀的编程知识分享平台

网站首页 > 技术文章 正文

告别崩溃!C#下载任务异常处理全攻略,小白也能秒懂!

nanyue 2024-08-16 19:49:56 技术文章 12 ℃

在C#编程中,我们经常需要通过网络下载文件或数据。然而,网络的不稳定性、目标服务器的问题等因素都可能导致下载任务失败。此时,如果不进行妥善处理,程序可能会崩溃或抛出异常,影响用户体验。对此,应该如何处理呢?

在传统的C#编程中,我们通常会使用try-catch语句来捕获和处理异常。但是,在处理异步操作时,这种方式可能会变得复杂。

看我以前的代码:

string url = "https://example.com/";
        Task<HttpResponseMessage> downloadTask = Task.Run(async () =>
        {
            using (var client = new HttpClient())
            {
                return await client.GetAsync(url);
            }
        });
Task<string> parseTask = downloadTask.ContinueWith(async (t1) =>
        {
            if (t1.Status == TaskStatus.RanToCompletion)
            {
                var response = t1.Result;
                if (response.IsSuccessStatusCode)
                {     
                  string data = await response.Content.ReadAsStringAsync();
                    // 解析数据(这里只是简单地返回数据)
                    return "解析后的数据: " + data;
                }
                else
                {
                    return "请求失败,状态码: " + response.StatusCode;
                }
            }
            else
            {
                return "下载任务失败";
            }
        });
// 使用ContinueWith来创建最终的任务,这个任务在parseTask完成后执行
        Task outputTask = parseTask.ContinueWith(t2 =>
        {
            // 输出解析后的数据
            Console.WriteLine(t2.Result);
        });
        // 等待输出任务完成
        await outputTask;

在代码中,我使用了Task.Run和ContinueWith来创建异步任务,并在每个任务中分别处理异常。这种方式虽然可以实现功能,但代码结构较为繁琐,不利于维护。

为了解决问题,一种更为简洁、优雅的异常处理方式是通过封装一个异步方法,将下载和解析操作合并到一个方法中,并在该方法内部使用try-catch语句来捕获和处理异常。这样,当下载任务失败时,直接抛出异常,并在主方法中捕获和处理它。是不是更好呢?

看我改进后的代码:

class Program
{
    static async Task Main(string[] args)
    {
        string url = "https://example.com/";
        try
        {
            var content = await DownloadAndParseAsync(url);
            Console.WriteLine(content);
        }
        catch (Exception ex)
        {
            Console.WriteLine("下载或解析过程中发生异常:" + ex.Message);
        }
    }
    static async Task<string> DownloadAndParseAsync(string url)
    {
        using (var client = new HttpClient())
        {
            var response = await client.GetAsync(url);
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpRequestException(#34;请求失败,状态码: {response.StatusCode}");
            }
            string data = await response.Content.ReadAsStringAsync();
            // 解析数据(这里只是简单地返回数据)
            return "解析后的数据: " + data;
        }
    }
}

首先,我定义了一个DownloadAndParseAsync方法,该方法接收一个URL作为参数,并返回下载并解析后的数据。

在方法内部,我使用HttpClient来发送GET请求,并使用await关键字来异步等待响应。

如果响应状态码表示成功,则读取响应内容并返回;否则,抛出HttpRequestException异常。

在主方法中,调用DownloadAndParseAsync方法并等待其结果。

如果下载和解析成功,则输出解析后的数据;否则,捕获HttpRequestException异常并输出其消息。

通过这种方式,可以实现简洁、优雅的异常处理。

那么,如果下载任务失败,代码将如何处理异常?

当下载任务失败时,HttpClient.GetAsync方法将返回一个非成功的HTTP状态码。

在DownloadAndParseAsync方法中,通过检查响应的状态码来判断是否成功。

如果状态码表示失败,则抛出HttpRequestException异常,并附带失败的状态码作为异常消息。

这样,在主方法中,我们就可以通过捕获这个异常来获知下载失败的原因,并进行相应的处理。从而避免了程序的崩溃和用户体验的下降。

你学会了吗?更多技巧可以和我交流额![呲牙]


最近发表
标签列表