jpo*_*pou 3 c# multithreading asynchronous async-await
我在 C# 中使用 async/await,虽然我认为我理解大多数概念,但我无法解释为什么代码行“var rxres = await ...”第一次在我的 UDP 线程上运行,之后数据包的进一步接收在工作线程上运行。据我所知,我没有“屈服”回线程函数,它仍然存在,因此所有对 ReceiveAsync 的调用都应该在我创建的线程上运行。
static void Main(string[] args)
{
var ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
var udpThread = new Thread(async () =>
{
ListenUdpAsync().Wait();
});
udpThread.Name = "UDP THREAD";
udpThread.Start();
ewh.WaitOne();
}
static public async Task ListenUdpAsync()
{
var localPort = 5555;
var localBind = new IPEndPoint(IPAddress.Any, localPort);
using (var udpc = new UdpClient(localBind))
{
while(true)
{
var rxres = await udpc.ReceiveAsync();
Console.WriteLine("Rx From: " + rxres.RemoteEndPoint);
Console.WriteLine("Rx Data: " + Encoding.ASCII.GetString(rxres.Buffer));
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不是“屈服”回到线程功能
该方法产生一次点击await udpc.ReceiveAsync(),这就是 async-await 的工作原理。ListenAsync自身同步阻塞,但由于没有同步上下文发挥作用,延续能够将自身编组到任意线程池线程上。
所以 ReceiveAsync 的所有调用都应该在我创建的线程上运行。
并不真地。通常,当您在控制台应用程序中运行时,它使用 default TaskScheduler,它在内部使用线程池在任意线程池线程上执行延续。一个ReceiveAsync()完成,它的延续需要安排在某个地方,那个地方在线程池上。
附带说明 - 没有理由async在委托上使用修饰符,因为您不是在等待内部的任何东西,而是同步阻塞。
| 归档时间: |
|
| 查看次数: |
464 次 |
| 最近记录: |