![](/img/trans.png)
[英]Why do some pages require access token and others don't in Graph API?
[英]Why do some async methods require a return type of Task, and others don't
在Microsoft的此示例中 ,該方法的返回類型為Task<int>
范例1:
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;
}
在第二個示例中,它使用async和await,但是BUT不返回Task <>類型,為什么?
范例2:
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
ReadCharacters();
}
static async void ReadCharacters()
{
String result;
using (StreamReader reader = File.OpenText("existingfile.txt"))
{
Console.WriteLine("Opened file.");
result = await reader.ReadToEndAsync();
Console.WriteLine("Contains: " + result);
}
}
}
}
第三,在第一個示例中,是否可以返回一個數組(字符串)?
在第二個示例中,它使用async和await,但是BUT不返回Task <>類型,為什么?
他們犯了一個錯誤。 每當創建異步且沒有返回值的方法時 ,它都應返回Task
。 唯一的例外是事件處理程序,您需要在其中與委托簽名保持兼容性,但事實並非如此。 將Task
視為異步方法的void
等效項。
為什么您實際上要返回一個Task
而不是void
? 因為返回Task
可以監視執行狀態,還可以正確處理封裝在正在進行的操作中的所有異常。
例如,考慮拋出一個async void
方法:
public async void WaitAndThrowAsync()
{
await Task.Delay(1000);
throw new Exception("yay");
}
public void CallWaitAndThrowAsync()
{
// What happens when it throws here?
WaitAndThrowAsync();
}
調用此方法時,您無法實際處理方法內部發生的異常,這對於調用站點來說是“一勞永逸”的事情。 但是,當您公開Task
,現在可以通過異步等待更好地處理該異常:
public async Task WaitAndThrowAsync()
{
await Task.Delay(1000);
throw new Exception("yay");
}
public async Task CallWaitAndThrowAsync()
{
try
{
await WaitAndThrowAsync();
}
catch (Exception e)
{
// Do something.
}
}
第三,在第一個示例中,是否可以返回一個數組(字符串)?
是的,通過返回Task<string[]>
:
public async Task<string> GetArrayAsync()
{
HttpClient client = new HttpClient();
var responseStream = await client.GetStreamAsync("http://msdn.microsoft.com");
using (var streamReader = new StreamReader(responseStream))
{
return await streamReader.ReadToEndAsync();
}
}
當您將方法標記為async
,編譯器將為您隱式創建一個Task
。 當您具有返回類型時,生成的任務是Task<T>
,其中T
是您的返回類型。
第二個例子不是一個很好的例子:由於async void
因此不再可能等待異步方法。 async void
應該僅用於事件處理程序。
對於第二個問題,是的,可以返回字符串數組。 只需使用Task<string[]>
。
我真的建議您閱讀Stephen Cleary的這篇出色文章: https : //msdn.microsoft.com/zh-cn/magazine/jj991977.aspx
本文中的一些最佳做法:
那一秒不符合Microsoft指定的准則 :
返回類型是以下類型之一:-如果您的方法具有一個返回語句,其中操作數的類型為TResult,則執行任務。 -如果您的方法沒有return語句或沒有操作數的return語句,則執行任務。 -無效(Visual Basic中的Sub),如果您正在編寫異步事件處理程序。
為什么方法應該返回Task
或Task<T>
?
每個返回的任務代表正在進行的工作。 任務封裝有關異步進程狀態的信息,最終封裝有關該進程的最終結果的信息,或者封裝如果該進程不成功則引發的異常的信息。
因此,當您使用void
時,您會丟失信息。 您將放棄實際的任務進度和執行信息。 因此,對於void
返回類型,請使用Task
。 對於任何其他類型,請使用Task<T>
,其中T
是實際的返回類型。
一些方法可以返回void
,但事件處理程序或啟動程序方法禁止這樣做:
異步方法也可以是Sub方法(Visual Basic)或具有void返回類型(C#)。 此返回類型主要用於定義事件處理程序,其中需要void返回類型。 異步事件處理程序通常用作異步程序的起點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.