c# – 如何从头开始实现异步I / O绑定操作?
我试图了解如何以及何时使用异步编程并进行I / O绑定操作,但我不理解它们.我想从头开始实现它们.我怎样才能做到这一点?
考虑下面的同步示例: private void DownloadBigImage() { var url = "https://cosmos-magazine.imgix.net/file/spina/photo/14402/180322-Steve-Full.jpg"; new WebClient().DownloadFile(url,"image.jpg"); } 如何通过仅使用正常的同步方法DownloadBigImage而不使用Task.Run来实现异步版本,因为这将仅使用线程池中的线程进行等待 – 这只是浪费! 也不要使用已经异步的特殊方法!这就是这个问题的目的:如何在不依赖已经异步的方法的情况下自己制作它?所以,没有像这样的事情: await new WebClient().DownloadFileTaskAsync(url,"image.jpg"); 在这方面非常缺乏可用的示例和文档.我发现只有这个:
基本上我必须使用“P / Invoke互操作调用到本机网络库”……但是如何? 解决方法
我认为这是一个非常有趣的问题,也是一个有趣的学习练习.
从根本上说,您不能使用任何同步的现有API.一旦它同步,就无法将其变为真正的异步.您正确地确定了Task.Run及其等价物不是解决方案. 如果拒绝调用任何异步.NET API,则需要使用PInvoke调用本机API.这意味着您需要调用WinHTTP API或直接使用套接字.这是可能的,但我没有经验来指导你. 相反,您可以使用异步托管套接字来实现异步HTTP下载. 从同步代码开始(这是一个原始草图): using (var s = new Socket(...)) { s.Connect(...); s.Send(GetHttpRequestBytes()); var response = new StreamReader(new NetworkStream(s)).ReadToEnd(); } 这非常粗略地将您的HTTP响应作为字符串. 您可以使用await轻松实现真正的异步. using (var s = new Socket(...)) { await s.ConnectAsync(...); await s.SendAsync(GetHttpRequestBytes()); var response = await new StreamReader(new NetworkStream(s)).ReadToEndAsync(); } 如果你考虑等待你的运动目标作弊,你需要使用回调来写这个.这太糟糕了,所以我只想写连接部分: var s = new Socket(...) s.BeginConnect(...,ar => { //perform next steps here },null); 同样,这段代码非常原始,但它显示了原理.您可以注册在IO完成时调用的回调,而不是等待IO完成(这隐式发生在Connect中).这样你的主线程继续运行.这会把你的代码变成意大利面条. 您需要使用回调编写安全处理.这是一个问题,因为异常处理不能跨越回调.此外,如果您不想依赖框架来执行此操作,则可能需要编写读取循环.异步循环可以是弯曲的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |