提问人:Hax 提问时间:3/28/2023 更新时间:3/28/2023 访问量:37
老式异步调用不会进入其回调方法
Oldish-way async call doesn't go into its callback method
问:
我试图找出 .Net 中 async-await 用法的祖先。在下面的代码中,我希望进入传递,但事实并非如此。缺少的点是什么?WebRequest
GetWebResponseCallback
BeginGetResponse
using System;
using System.Net;
using System.Threading;
using Newtonsoft.Json;
class X
{
public static void GetWebResponseCallback(IAsyncResult result)
{
Console.WriteLine("test");
WebRequest request = (WebRequest)result.AsyncState;
WebResponse response = request.EndGetResponse(result);
Console.WriteLine(JsonConvert.SerializeObject(response));
}
// read the data, and process it...
public static void GetWebResponse(string url)
{
WebRequest request = WebRequest.CreateHttp(url);
/*WebResponse response = request.GetResponse();
// read the data and process it...
Console.WriteLine(JsonConvert.SerializeObject(response));
*/
request.BeginGetResponse(GetWebResponseCallback, request);
}
public static void Main(string[] args)
{
var url = "https://github.com/timbrel/GitSavvy/actions/workflows/lint.yml/badge.svg"; ;
GetWebResponse(url);
Console.WriteLine("hax");
}
}
答:
1赞
Vadim Martynov
3/28/2023
#1
您的应用程序不等待完成响应,并在您调用 和 后立即关闭。这就是为什么在程序终止之前根本没有时间执行的原因。GetWebResponse
Console.WriteLine
GetWebResponseCallback
您可以在 main 方法中添加一些等待以防止终止程序:
public static void Main(string[] args)
{
var url = "https://github.com/timbrel/GitSavvy/actions/workflows/lint.yml/badge.svg"; ;
GetWebResponse(url);
Console.WriteLine("hax");
// wait for user input
Console.ReadLine();
}
这不是一个生产就绪的解决方案,但它足以证明回调函数是在请求完成后执行的。在更复杂的方案中,可以使用同步机制(如 ManualResetEvent
)显式等待完成信号。
ManualResetEvent 类表示一个线程同步事件,当发出信号时,必须手动重置该事件。此类不能被继承。
您可以创建一个实例,将其作为状态传递给回调,并在回调函数中调用它:ManualResetEvent
class X
{
public static void GetWebResponseCallback(IAsyncResult result)
{
Console.WriteLine("test");
var state = (RequestState)result.AsyncState;
WebResponse response = state.Request.EndGetResponse(result);
Console.WriteLine(JsonConvert.SerializeObject(response));
// send signal that async operation is complete
state.CompleteEvent.Set();
}
public static void GetWebResponse(string url, ManualResetEvent manualResetEvent)
{
WebRequest request = WebRequest.CreateHttp(url);
var state = new RequestState { Request = request, CompleteEvent = manualResetEvent };
request.BeginGetResponse(GetWebResponseCallback, state);
}
public static void Main(string[] args)
{
var url = "https://github.com/timbrel/GitSavvy/actions/workflows/lint.yml/badge.svg";
var manualResetEvent = new ManualResetEvent(false);
GetWebResponse(url, manualResetEvent);
Console.WriteLine("soner");
// Wait for async operation to complete
manualResetEvent.WaitOne();
}
public class RequestState
{
public WebRequest Request { get; set; }
public ManualResetEvent CompleteEvent { get; set; }
}
}
评论