我知道我需要在async
标记的方法中等待它以使其异步,但我不知道如何实际结束它所造成的漏洞。
static async void Example()
{
int t = await getIntAsync();
WriteLine($"computer: {t}");
}
由于getIntAsync被标记为异步,我必须在该方法中等待,否则我会收到警告。但是我在getIntAsync等待的方法中没有,我必须将其标记为aasync,然后除非在那里有await我得到警告。似乎等等,无穷无尽。我该如何让它停下来?
我有几个人告诉我要把
await Task.Delay(1000);
在我的代码中,但我知道答案不会像在我的所有生产代码中延迟一秒那样臭。
其他几个人说了一个结束它的任务方法,如
static Task task()
{
//code
}
但除非我标记async
,否则它会引发同样的警告,让我陷入混乱。我知道
static Task task()
{
//code
return Task.FromResult(0);
}
从技术上讲它是有效的,但是再次看起来太多的代码味道都无法生产。
我只是不明白......
编辑: 因为它被要求。我知道它是一种非常简单的方法,但它也只是我用于练习的方法。
static async Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
int n = int.Parse(Console.ReadLine());
return n;
}
答案 0 :(得分:4)
这里令人困惑的是你并没有真正做某事异步。 Console.ReadLine()
是一种同步方法。只需在某处键入async
或await
就不会奇怪地使其异步。
由于此代码仅用于测试和学习,因此将其设置为异步的一种方法是使用Task.Run()
将其放在另一个线程上(我不建议在生产代码中使用这种情况):
static Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
return Task.Run(() => int.Parse(Console.ReadLine());
}
此处不需要async
个关键字,因为您没有等待。您只需返回用户输入值并且已解析该值时已完成的Task<int>
。
然后您的Example()
方法就是这样:
static async void Example()
{
int t = await getIntAsync();
WriteLine($"computer: {t}");
}
当命中await
时,控制流将返回给调用者,此方法的其余部分(分配到t
和调用Console.WriteLine()
)被安排为<{1}}返回的Task<int>
完成后执行的延续。
答案 1 :(得分:0)
需要以下内容(async关键字是必需的,等待,它只是最佳做法):
以下是使用StreamReader的示例
async Task<string> GetStringFromReaderAsync()
{
Streamreader sr = new StreamReader("filename.txt");
Task<string> getStringTask = sr.ReadLineAsync("filepath");
//Allow user to continue with some other work.
DoFileLookup();
string result = await sr.getStringTask();
return result.ToString();
}
此处提供更多信息:https://msdn.microsoft.com/en-us/library/system.io.streamreader.readlineasync(v=vs.110).aspx
有关Async和Await的更多信息:https://msdn.microsoft.com/en-us/library/mt674882.aspx
答案 2 :(得分:0)
static async Task<int> getIntAsync() { Console.Write("Enter the number: "); int n = int.Parse(Console.ReadLine()); return n; }
这将同步运行,因为没有await语句并且没有等待异步方法的调用
一般的想法就是这个
public async Task<int> ExecuteAsync() //Method return type is Task<int>
{
// Error: return type is not int. Return type is Task<int>
return db.SaveChangesAsync();
// OK: returns a task handle that you can await on in you code that called ExecuteAsync()
// you thread continues processing in your calling function until you try to read the value from this return statement.
return await db.SaveChangesAsync();
// Ok. Your Thread leaves here and returns when result available.
// no further Processing done in calling function
return db.SaveChangesAsync().Result;
// Ok. This is not required in this case,
// but if you have an async method that has multiple return points,
// and one of them does not depend on an async method, you can wrap
// the output e.g. return await Task.FromResult(0);
return await Task.FromResult(db.SaveChangesAsync().Result);
return 0; //also ok.
}
添加下面的其他答案。
static async Task<int> GetIntAsync()
{
Console.Write("Enter the number: ");
return await Task.Run(() => int.Parse("1"));
}
这种方法使得同步运行的东西被包装在任务中。但是你永远不应该这样做(除非你知道你在做什么),因为这会产生另一个线程。我使用过它的一个用例是在web服务器上卸载,但通常情况下这是一个坏主意。因此,虽然您可能已经开始意图最大限度地利用单个线程,但现在您已经完成了两个线程工作。