nul*_*ull 0 .net c# asynchronous async-await
我将raspberry pi设置为服务器,通过HTTP将json作为输入."API"允许设置连接到pi的LED.一切正常,我可以从浏览器发送请求,一切都很好.
到达时,响应需要一段时间.这就是我想要异步沟通的原因.
Run Code Online (Sandbox Code Playgroud)// Three things to note in the signature: // - The method has an async modifier. // - The return type is Task or Task<T>. (See "Return Types" section.) // Here, it is Task<int> because the return statement returns an integer. // - The method name ends in "Async." async Task<int> AccessTheWebAsync() { // You need to add a reference to System.Net.Http to declare client. HttpClient client = new HttpClient(); // GetStringAsync returns a Task<string>. That means that when you await the // task you'll get a string (urlContents). Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork(); // The await operator suspends AccessTheWebAsync. // - AccessTheWebAsync can't continue until getStringTask is complete. // - Meanwhile, control returns to the caller of AccessTheWebAsync. // - Control resumes here when getStringTask is complete. // - The await operator then retrieves the string result from getStringTask. string urlContents = await getStringTask; // The return statement specifies an integer result. // Any methods that are awaiting AccessTheWebAsync retrieve the length value. return urlContents.Length; }
对于顶级概述,这是我的Main方法的样子(它不编译):
var pi1 = new RaspberryPi(@"http://192.168.0.100:8080"); // specify IP
var led = new Led(255, 100, 180); // r, g, b values wrapped in an Led object
Led result = await pi1.setLedAsync(2, led); // FAIL // what should be an async POST, awaiting the response
Run Code Online (Sandbox Code Playgroud)
我希望这是有道理的.
的Led类只是保持3个中的数据对象byteS为3个信道和一些转换方法和从JSON.
该setLedAsync方法:
async public Task<Led> setLedAsync(uint n, Led led)
{
var client = new HttpClient();
client.BaseAddress = _uri;
var content = new StringContent(led.ToJson(), Encoding.UTF8, "application/json");
Task<HttpResponseMessage> response = client.PutAsync("/led/" + n, content);
HttpResponseMessage responseMessage = await response;
string json = await responseMessage.Content.ReadAsStringAsync();
return new Led(json);
}
Run Code Online (Sandbox Code Playgroud)
这行是我收到使用错误的地方await:
Led result = await pi1.setLedAsync(2, led);
Run Code Online (Sandbox Code Playgroud)
await只能在async方法中使用.
为什么我会收到此错误?示例代码中的最后一个注释行
//等待AccessTheWebAsync的任何方法都会检索长度值.
让我觉得应该这样做.据我所知,它await基本上解开Task<T>了T.
如果我不使用await,我得到一个类型不匹配,因为该方法返回Task<Led>,而不是Led.
令我感到困惑的是理解示例和我的情况之间的区别.我必须await在我的async方法中使用两次:
HttpResponseMessage responseMessage = await response;string json = await responseMessage.Content.ReadAsStringAsync();问题在于我必须以HttpResponseMessage中间人的身份对待这个问题.我怀疑我过早地放弃了异步性,等待某种方式等待(如果这有任何意义)我认为这是问题的根源,但我不确定如何解决它.
我将函数调用包装在一个asyn方法中,该方法允许编译代码.但它不是异步的.我在服务器端添加了一个延迟来测试它.
class Program
{
static void Main(string[] args)
{
var prog = new Program();
Console.WriteLine("before init");
prog.init();
Console.WriteLine("after init"); // not happening before the response arrives
Console.Read();
}
private async void init()
{
var pi1 = new RaspberryPi(@"http://192.168.0.100:8080"); // specify IP
var led = new Led(255, 0, 0); // r, g, b values wrapped in an Led object
Console.WriteLine("before await");
Led result = await pi1.setLedAsync(2, led); // what should be an async POST, awaiting the response
Console.WriteLine("after await");
}
}
Run Code Online (Sandbox Code Playgroud)
在请求的响应到来之前,没有"after"消息写入控制台.
您得到错误是因为异步等待 - 等待 - 意味着执行等待的方法本身是异步的.我想你不明白等待意味着什么.等待并没有意味着同步阻塞,直到结果可用 -这是相反的是什么意思.等待意味着立即返回,以便我的呼叫者可以在不等待此结果的情况下完成重要工作; 在结果可用时,在将来的某个时间安排此方法的其余部分.Await是异步等待.当你等待一封信到达邮件时,你不会坐在门边,什么都不做,直到它到来; 你以异步方式完成其他工作,然后在信件到达后的某个时间恢复阅读邮件的任务.
你说方法 - 等待的方法,而不是等待返回任务的方法 - 是Main.如果这是一个控制台应用程序,那么你不能使Main异步,因为当Main返回程序结束时.再次,内化这个:await只是从当前方法的角度来看.当前的方法将在稍后的时间再次调用,并将在它停止的地方继续调用,但是当Main返回时,没有未来.所以你不能使主要异步.
您注意到异步将T的任务转换为T,这是正确的,但它是异步的.所以你在这里的主要选择是:
| 归档时间: |
|
| 查看次数: |
1715 次 |
| 最近记录: |