使用.NET 4.5和C#5.0對此進行編碼async/await
是very easy。
如果必須,也可以使其與.NET 4.0/C#4.0異步工作。您需要從AsyncController
派生您的控制器並使用AsyncManager
。基本步驟在"Using an Asynchronous Controller in ASP.NET MVC"中描述。
鑑於此,你的代碼可能看起來像這樣(未經):
static public Task<WebResponse> GetResponseTapAsync(this WebRequest request)
{
return Task.Factory.FromAsync(
(asyncCallback, state) =>
request.BeginGetResponse(asyncCallback, state),
(asyncResult) =>
request.EndGetResponse(asyncResult), null);
}
// ...
public class YourController : AsyncController
{
public void YourMethodAsyc(string url)
{
AsyncManager.OutstandingOperations.Increment();
var request = (HttpWebRequest)WebRequest.Create(url);
request.GetResponseTapAsync().ContinueWith(responseTask =>
{
try
{
var stream = responseTask.Result.GetResponseStream();
using (var streamReader = new StreamReader(stream))
{
// still blocking here, see notes below
var data = streamReader.ReadToEnd();
AsyncManager.Parameters["data"] = data;
}
}
finally
{
AsyncManager.OutstandingOperations.Decrement();
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
public ActionResult YourMethodCompleted(string data)
{
return View("Data", new ViewModel
{
Data = data
});
}
}
你可以把它進一步貫徹ReadToEndAsync
(因爲它是在.NET 4.0中不存在),但你不會能夠使用using
。查看this瞭解更多詳情。理想情況下,如果您需要使用.NET 4.0針對ASP.NET MVC,但使用C#5.0中的VS2012 +進行開發,則仍然可以使用async/await
,Microsoft爲此提供了Microsoft.Bcl.Async
庫。然後你的代碼可能看起來像這樣:
public class YourController : AsyncController
{
async Task<string> YourMethodAsyncImpl(string url)
{
var request = (HttpWebRequest)WebRequest.Create(url);
using (var response = await request.GetResponseAsync()
using (var streamReader = new StreamReader(response.GetResponseStream())
return await streamReader.ReadToEndAsync();
}
public void YourMethodAsyc(string url)
{
AsyncManager.OutstandingOperations.Increment();
YourMethodAsyncImpl(url).ContinueWith(resultTask =>
{
try
{
AsyncManager.Parameters["data"] = resultTask.Result;
}
finally
{
AsyncManager.OutstandingOperations.Decrement();
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
public ActionResult YourMethodCompleted(string data)
{
return View("Data", new ViewModel
{
Data = data
});
}
}
您的CallServiceNonBlocking必須在完成抓取時執行完成處理程序/回調。您*可以*使用.NET 4.0中的TPL。 – vcsjones
你能告訴我這看起來好嗎? –
您可能想查看:http://msdn.microsoft.com/en-us/library/dd997423(v=vs.100).aspx – PCG