C# 无任务异步等待<;T>;方法
根据MSDN中的示例:C# 无任务异步等待<;T>;方法,c#,.net,asynchronous,async-await,C#,.net,Asynchronous,Async Await,根据MSDN中的示例: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using Syst
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Add a using directive and a reference for System.Net.Http;
using System.Net.Http;
namespace AsyncFirstExample
{
public partial class MainWindow : Window
{
// Mark the event handler with async so you can use await in it.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
// Call and await separately.
//Task<int> getLengthTask = AccessTheWebAsync();
//// You can do independent work here.
//int contentLength = await getLengthTask;
int contentLength = await AccessTheWebAsync();
resultsTextBox.Text +=
String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
}
// 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;
}
void DoIndependentWork()
{
resultsTextBox.Text += "Working . . . . . . .\r\n";
}
}
}
// Sample Output:
// Working . . . . . . .
// Length of the downloaded string: 41564.
现在如何返回str
像这样:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Add a using directive and a reference for System.Net.Http;
using System.Net.Http;
namespace AsyncFirstExample
{
public partial class MainWindow : Window
{
// Mark the event handler with async so you can use await in it.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
// Call and await separately.
//Task<int> getLengthTask = AccessTheWebAsync();
//// You can do independent work here.
//int contentLength = await getLengthTask;
int contentLength = await AccessTheWebAsync();
resultsTextBox.Text +=
String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
}
// 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()
{
// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = GetMyString(); // here
// 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;
}
void DoIndependentWork()
{
resultsTextBox.Text += "Working . . . . . . .\r\n";
}
}
}
private Task<string> GetMyString()
{
string str = string.Empty;
for (int i = 0; i < 1000000000; i++)
{
// compute str using simple c# code
}
// How to return str now?
}
private async Task<string> GetMyString()
{
string str = string.Empty;
for (int i = 0; i < 1000000000; i++)
{
// compute str using simple c# code
}
return str;
}
Task getStringTask=Task.Run(()=>GetMyString());
那么GetMyString
在任何有用的方面都是异步的吗?如果不是,当您将它与需要适当异步代码的代码一起使用时(即,它几乎立即返回,任务将在稍后完成)。您的问题是什么?不,GetMyString
不是异步的。但我还是想打电话asynchronous@yazanpro,您的意思是希望它在另一个线程中运行吗?这与异步不同……是的,我似乎希望它在另一个线程中运行。我一定把这两个概念搞混了!使用单独的线程正是我所需要的。然而,为了让答案更完整,请参考“因为GetMyString的实现不是异步的”,您能否详细说明如何以异步方式实现GetMyString
?另外,请说明如何防止return str引起的编译器错误
@yazanpro不,您的实现思想不是异步的。例如,如果您实际上正在从web服务器接收数据,这是一个异步I/O操作,并且不会占用任何线程。您正在进行CPU工作,因此没有机会使用异步I/O,只能使用并行(最多)。这两个概念非常不同,而Task
和Task
的定义方式使这一点相当混乱。@yazanpro因此Task.Run
返回的任务基本上是对刚刚创建的CPU工作线程的异步I/O,但您正在做的实际工作仍然是CPU工作,非异步I/O。在不使用Wait的情况下使用async关键字实现方法会引发编译器警告。您可以删除async关键字并使用“return Task.FromResult(str)”代替。
private string GetMyString()
{
string str = string.Empty;
for (int i = 0; i < 1000000000; i++)
{
// compute str using simple c# code
}
return str;
}
Task<string> getStringTask = Task.Run(() => GetMyString());