如何将同步的VB.NET Web请求函数转换为异步方法?
如何将同步的VB.NET Web请求函数转换为异步方法?
我来帮你把这个同步的Web请求函数改成异步版本,其实现在更推荐用HttpClient(原生支持异步,API更简洁),不过我也会提供基于你原有HttpWebRequest的异步改造方案,同时附上C#版本供参考~
一、VB.NET 实现方案
1. 推荐:使用 HttpClient 异步版本
HttpClient是.NET中官方推荐的HTTP请求工具,异步支持更完善,而且建议复用同一个实例(不要每次请求都新建,避免耗尽套接字资源)。
Imports System.Net.Http Imports System.Threading.Tasks ' 建议把HttpClient作为类的静态成员复用,避免频繁创建释放 Private Shared ReadOnly _httpClient As New HttpClient() Public Async Function GetPostWebServiceAsync(urlget As String, stringdata As String) As Task(Of String) Try ' 先检查网络状态 If Not internet_on_line Then Return "[ERROR]" End If ' 构建请求URL,和原逻辑一致 Dim milliseconds = CLng(DateTime.UtcNow.Subtract(New DateTime(1970, 1, 1)).TotalMilliseconds) Dim uncache = milliseconds.ToString() Dim url = $"https://{apiUrl}/webservice/{urlget}&data={stringdata}&uncache={uncache}" Console.WriteLine("URL: " & url) ' 设置HttpClient的相关配置(比如TLS1.2、UserAgent) _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/4.0 (compatible)") ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 ' 异步发送GET请求并获取响应内容 Dim result = Await _httpClient.GetStringAsync(url) Return result Catch ex As Exception Console.WriteLine($"GetPostWebServiceAsync Falhou: {ex.Message}") ' 修正原代码的顺序:先处理异常再返回错误标识 Dim funcName = New StackTrace(ex).GetFrame(0).GetMethod().Name If funcName = "GetStringAsync" Then writeExeption(ex, False) Else writeExeption(ex, True) End If Return "[ERROR]" End Try End Function
2. 基于原有 HttpWebRequest 的异步改造
如果你想保留原有的HttpWebRequest逻辑,只需要把同步方法替换为对应的异步版本(比如GetResponseAsync代替GetResponse,异步读取流):
Imports System.Net Imports System.IO Imports System.Threading.Tasks Public Async Function GetPostWebServiceAsync(urlget As String, stringdata As String) As Task(Of String) Dim result As String = "" Try If Not internet_on_line Then Return "[ERROR]" End If Dim milliseconds = CLng(DateTime.UtcNow.Subtract(New DateTime(1970, 1, 1)).TotalMilliseconds) Dim uncache = milliseconds.ToString() Dim url = $"https://{apiUrl}/webservice/{urlget}&data={stringdata}&uncache={uncache}" Console.WriteLine("URL: " & url) ServicePointManager.Expect100Continue = True ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Dim targetURI As New Uri(url) Dim fr = DirectCast(WebRequest.Create(targetURI), HttpWebRequest) fr.UserAgent = "Mozilla/4.0 (compatible)" fr.Timeout = 15000 ' 异步获取响应 Using response = Await fr.GetResponseAsync() ' 异步读取流内容 Using stream = response.GetResponseStream() Using str As New StreamReader(stream) result = Await str.ReadToEndAsync() End Using End Using End Using Return result Catch ex As Exception Console.WriteLine($"GetPostWebServiceAsync Falhou: {ex.Message} - {result}") ' 修正原代码的顺序:先处理异常再返回错误标识 Dim funcName = New StackTrace(ex).GetFrame(0).GetMethod().Name If funcName = "GetResponseAsync" Then writeExeption(ex, False) Else writeExeption(ex, True) End If Return "[ERROR]" End Try End Function
二、C# 实现方案
1. HttpClient 异步版本
using System; using System.Net.Http; using System.Threading.Tasks; public class WebServiceHelper { // 复用HttpClient实例,避免频繁创建 private static readonly HttpClient _httpClient = new HttpClient(); public async Task<string> GetPostWebServiceAsync(string urlget, string stringdata) { try { if (!internet_on_line) // 确保internet_on_line变量在当前上下文可用 return "[ERROR]"; long milliseconds = (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds; string uncache = milliseconds.ToString(); string url = $"https://{apiUrl}/webservice/{urlget}&data={stringdata}&uncache={uncache}"; Console.WriteLine($"URL: {url}"); _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/4.0 (compatible)"); System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; string result = await _httpClient.GetStringAsync(url); return result; } catch (Exception ex) { Console.WriteLine($"GetPostWebServiceAsync Failed: {ex.Message}"); var funcName = new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name; if (funcName == "GetStringAsync") writeExeption(ex, false); // 确保writeExeption方法在当前上下文可用 else writeExeption(ex, true); return "[ERROR]"; } } }
2. HttpWebRequest 异步版本
using System; using System.IO; using System.Net; using System.Threading.Tasks; public async Task<string> GetPostWebServiceAsync(string urlget, string stringdata) { string result = ""; try { if (!internet_on_line) return "[ERROR]"; long milliseconds = (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds; string uncache = milliseconds.ToString(); string url = $"https://{apiUrl}/webservice/{urlget}&data={stringdata}&uncache={uncache}"; Console.WriteLine($"URL: {url}"); ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; Uri targetURI = new Uri(url); HttpWebRequest fr = (HttpWebRequest)WebRequest.Create(targetURI); fr.UserAgent = "Mozilla/4.0 (compatible)"; fr.Timeout = 15000; // 异步获取响应 using (var response = await fr.GetResponseAsync()) { using (var stream = response.GetResponseStream()) { using (var str = new StreamReader(stream)) { result = await str.ReadToEndAsync(); } } } return result; } catch (Exception ex) { Console.WriteLine($"GetPostWebServiceAsync Failed: {ex.Message} - {result}"); var funcName = new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name; if (funcName == "GetResponseAsync") writeExeption(ex, false); else writeExeption(ex, true); return "[ERROR]"; } }
关键注意点
- 异步方法需要用
Async(VB.NET)/async(C#)关键字修饰,返回类型为Task(Of T)(VB.NET)/Task<T>(C#) - 所有同步的阻塞调用都要替换为对应的异步版本,并用
Await(VB.NET)/await(C#)等待完成 - 修正了原代码的逻辑错误:原Catch块中
Return语句会跳过后续的异常处理代码,现在调整为先处理异常再返回错误标识 HttpClient建议复用实例,不要每次请求都新建,避免耗尽套接字资源
备注:内容来源于stack exchange,提问作者Luiz
相关产品推荐
相关产品推荐

