[英]Making a method asynch
我有一個叫Bing Api的方法。
IEnumerable<WebResult> Search(string query)
我想使此異步,以便如果我對其進行多次調用,則這些調用中的每個調用都是獨立的。 因此,按照這里的建議,我將簽名更改為
async Task<IEnumerable<WebResult>> SearchAsynch(string query)
但是我得到警告
This async method lacks 'await' operators and will run synchronously...
我希望整個方法都是異步的(至少我認為應該這樣)。 我怎么做? 這是我的代碼
public async Task<IEnumerable<WebResult>> SearchAsynch(string query)
{
if (query == null)
{
throw new ArgumentNullException("query cannot be null");
}
DataServiceQuery<WebResult> webQuery = _bingContainer.Web(query, null, null, null, null, null, null, null);
IEnumerable<WebResult> webResults = webQuery.Execute();
return webResults;
}
問題是我不確定這段代碼要等待什么。
async
關鍵字不會創建新的異步操作,它只是一種更輕松地為已存在的任務(即異步操作)配置延續的方法。
在這種情況下, DataServiceQuery
類已經提供了一種異步執行查詢的方法。 不幸的是,它使用的是舊的異步模型,而不是新的基於Task
的模型,因此您需要使用Task.Factory.FromAsync
進行翻譯:
public Task<IEnumerable<WebResult>> SearchAsynch(string query)
{
DataServiceQuery<WebResult> webQuery = _bingContainer.Web(query, null, null, null, null, null, null, null);
return Task.Factory.FromAsync(webQuery.BeginExecute(null, null)
, asyncResult => webQuery.EndExecute(asyncResult)));
}
在這種特殊情況下,由於除了創建任務外您無需執行任何操作,因此根本不需要async
或await
,因此您只需返回構造的任務即可。 如果您想在得到結果之后做點什么,可以await
任務:
public async Task<IEnumerable<WebResult>> SearchAsynch(string query)
{
DataServiceQuery<WebResult> webQuery = _bingContainer.Web(query, null, null, null, null, null, null, null);
var results = await Task.Factory.FromAsync(webQuery.BeginExecute(null, null)
, asyncResult=> webQuery.EndExecute(asyncResult));
Console.WriteLine("Hi there");
return results;
}
我對Bing API並不是很熟悉,但是如果API不包含異步方法,則可以通過將調用包裝在啟動的Task
來使一個異步。 async
修飾符不會使您的方法自動地異步,它僅允許await
內部的其他異步方法。
因此,就您而言,這可能是最簡單的:
public Task<IEnumerable<WebResult>> SearchAsync(string query)
{
if (query == null)
{
throw new ArgumentNullException("query cannot be null");
}
return Task.Run(() =>
{
DataServiceQuery<WebResult> webQuery = _bingContainer.Web(query, null, null, null, null, null, null, null);
return webQuery.Execute();
}
}
然后,您可以在其他標記為async
方法中await
該方法:
var result = await SearchAsync("yourQuery");
如果Bing API具有異步方法對Begin/End
,則可以使用Task.Factory.FromAsync
從異步方法對創建任務。 Servy的答案在那里有更詳細的說明。
每個MSDN
通常,由async關鍵字修改的方法至少包含一個await表達式或語句。 該方法將同步運行,直到到達第一個await表達式為止,此時該方法將被掛起,直到完成等待的任務。 同時,控制權返回給方法的調用者。 如果該方法不包含await表達式或語句,則它將同步執行。 編譯器警告您任何不包含等待狀態的異步方法,因為這種情況可能表示錯誤,從而警告您。 有關更多信息,請參見編譯器警告(等級1)CS4014。
編輯:我想我會添加到這,但它已經在這篇文章的評論部分。 標記為async
的方法只有在命中await
關鍵字后才真正運行異步。
這是在獨立項目中使用異步的示例。
private async void button2_Click(object sender, EventArgs e)
{
DataTable dtMessages = await getMessages2(string sqlConn2, nMessage);
}
public async Task<DataTable> getMessages2(string sqlConn, int n)
{
//create your query and command
var o = await cmd2.ExecuteReaderAsync();
DataTable dtMessages = o;
return dtMessages;
}
警告只是告訴您,無論您在哪里調用SearchAsynch,都需要等待它。
var result = await SearchAsynch(query);
但是,SearchAsynch沒有如其他人所述正確實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.