Jas*_*son 149 .net c# asynchronous httprequest
如何异步使用HttpWebRequest(.NET,C#)?
Jon*_*n B 123
使用 HttpWebRequest.BeginGetResponse()
HttpWebRequest webRequest;
void StartWebRequest()
{
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
webRequest.EndGetResponse(result);
}
Run Code Online (Sandbox Code Playgroud)
异步操作完成时调用回调函数.您至少需要EndGetResponse()从此功能调用.
xla*_*rsx 65
考虑到答案:
HttpWebRequest webRequest;
void StartWebRequest()
{
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
webRequest.EndGetResponse(result);
}
Run Code Online (Sandbox Code Playgroud)
您可以发送请求指针或任何其他对象,如下所示:
void StartWebRequest()
{
HttpWebRequest webRequest = ...;
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), webRequest);
}
void FinishWebRequest(IAsyncResult result)
{
HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
}
Run Code Online (Sandbox Code Playgroud)
问候
Isa*_*sak 62
到目前为止,每个人都错了,因为BeginGetResponse()有些人在当前的线程上工作.从文档:
在此方法变为异步之前,BeginGetResponse方法需要完成一些同步设置任务(例如,DNS解析,代理检测和TCP套接字连接).因此,永远不应在用户界面(UI)线程上调用此方法,因为在抛出错误的异常之前,可能需要相当长的时间(最多几分钟,具体取决于网络设置)才能完成初始同步设置任务.方法成功.
所以要做到这一点:
void DoWithResponse(HttpWebRequest request, Action<HttpWebResponse> responseAction)
{
Action wrapperAction = () =>
{
request.BeginGetResponse(new AsyncCallback((iar) =>
{
var response = (HttpWebResponse)((HttpWebRequest)iar.AsyncState).EndGetResponse(iar);
responseAction(response);
}), request);
};
wrapperAction.BeginInvoke(new AsyncCallback((iar) =>
{
var action = (Action)iar.AsyncState;
action.EndInvoke(iar);
}), wrapperAction);
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过响应执行所需操作.例如:
HttpWebRequest request;
// init your request...then:
DoWithResponse(request, (response) => {
var body = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.Write(body);
});
Run Code Online (Sandbox Code Playgroud)
Nat*_*lch 58
到目前为止,最简单的方法是使用TaskFactory.FromAsync从TPL.当与新的async/await关键字一起使用时,它实际上是几行代码:
var request = WebRequest.Create("http://www.stackoverflow.com");
var response = (HttpWebResponse) await Task.Factory
.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null);
Debug.Assert(response.StatusCode == HttpStatusCode.OK);
Run Code Online (Sandbox Code Playgroud)
如果您不能使用C#5编译器,则可以使用Task.ContinueWith方法完成上述操作:
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null)
.ContinueWith(task =>
{
var response = (HttpWebResponse) task.Result;
Debug.Assert(response.StatusCode == HttpStatusCode.OK);
});
Run Code Online (Sandbox Code Playgroud)
我最终使用了BackgroundWorker,它绝对是异步的,不像上面的一些解决方案,它处理返回GUI线程,它很容易理解.
它也很容易处理异常,因为它们最终出现在RunWorkerCompleted方法中,但请确保您阅读:BackgroundWorker中的未处理异常
我使用过WebClient但显然你可以使用HttpWebRequest.GetResponse.
var worker = new BackgroundWorker();
worker.DoWork += (sender, args) => {
args.Result = new WebClient().DownloadString(settings.test_url);
};
worker.RunWorkerCompleted += (sender, e) => {
if (e.Error != null) {
connectivityLabel.Text = "Error: " + e.Error.Message;
} else {
connectivityLabel.Text = "Connectivity OK";
Log.d("result:" + e.Result);
}
};
connectivityLabel.Text = "Testing Connectivity";
worker.RunWorkerAsync();
Run Code Online (Sandbox Code Playgroud)
自从发布了许多这些答案以来,.NET已经发生了变化,我想提供一个更新的答案.使用异步方法启动Task将在后台线程上运行的方法:
private async Task<String> MakeRequestAsync(String url)
{
String responseText = await Task.Run(() =>
{
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
return new StreamReader(responseStream).ReadToEnd();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
return null;
});
return responseText;
}
Run Code Online (Sandbox Code Playgroud)
要使用异步方法:
String response = await MakeRequestAsync("http://example.com/");
Run Code Online (Sandbox Code Playgroud)
更新:
此解决方案不适用于WebRequest.GetResponseAsync()替代使用的UWP应用程序WebRequest.GetResponse(),并且它不会Dispose()在适当的地方调用方法.@dragansr有一个很好的替代解决方案来解决这些问题.
public static async Task<byte[]> GetBytesAsync(string url) {
var request = (HttpWebRequest)WebRequest.Create(url);
using (var response = await request.GetResponseAsync())
using (var content = new MemoryStream())
using (var responseStream = response.GetResponseStream()) {
await responseStream.CopyToAsync(content);
return content.ToArray();
}
}
public static async Task<string> GetStringAsync(string url) {
var bytes = await GetBytesAsync(url);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
167975 次 |
| 最近记录: |