假设我有一个定义如下的方法:
public async Task CreateUser()
{
await GetUserDetails();
GetUserOrder();
}
private void GetUserDetails() {
private void GetUserOrder() {
方法GetUserDetails();
和GetUserOrder()
是否必须async
以避免UI阻止?
我不能await
GetUserDetails()
方法,因为它不是异步的。我怎样才能在c#中实现这一目标?我想确保一步一步地调用所有这些方法。
答案 0 :(得分:8)
相关问题在评论中:
如何确保所有方法都按顺序完全调用?
你问这个问题的事实表明你不明白“等待”是什么。 Await是异步工作流程的排序操作。 await
表示此等工作流将在等待任务完成之前继续。这是异步等待,因此名称为await
。
考虑这个问题:在同步工作流程中,排序操作是什么?
不,真的,请考虑一下。
是;
。当你说
fResult = foo();
bResult = bar();
qResult = qux();
这意味着foo必须在bar开始之前完全完成。 异步工作流程不适用。如果我们有
fTask = fooAsync();
bTask = barAsync();
qTask = quxAsync();
然后异步操作可以按任何顺序完成。如果我们说
await fooAsync();
await barAsync();
await quxAsync();
然后 barAsync将在fooAsync的任务完成后才会启动。 await
序列异步工作流程。区别在于,线程可以继续执行其他不相关的工作,同时异步等待foo完成,这在同步工作流中不是这样;在同步工作流中,线程已经忙于计算foo结果,因此无法完成其他工作。
答案 1 :(得分:1)
是的,如果你想等待,你也必须为这些方法写await
。因为在第一次等待你的代码之后,agian将是同步的..如果UI线程将在它上运行。
1.您的代码将是,因此通过此代码,您的代码也变为GetUserORder的异步。你只需要在Task构造中包装方法并返回
public async Task CreateUser()
{
await GetUserDetails();
await Task.Factory.SartNew(()=> GetUserOrder());
}
2.或者你也可以这样做
public async Task CreateUser()
{
await Task.Factory.SartNew(()=>{
GetUserDetails();
GetUserOrder(); });
}
3.或者你也可以这样做,在下面的代码中不会等待getuserorder方法并执行等待一个方法
public async Task CreateUser()
{
Task.Factory.SartNew(()=> GetUserOrder()).ContinueWith((t)=> Console.WriteLine("Completed");
await GetUserDetails();
}
4.或者最后一个变体,在这里你首先启动GetUserOrder并且不要等待它,而不是以异步方式调用GetUserDetails,如果你想使用GetUserOrder方法想要等待只使用Wait方法。
public async Task CreateUser()
{
var task = Task.Factory.SartNew(()=> GetUserOrder());
await GetUserDetails();
if(!task.IsCompleted)
task.Wait();
}
在你的情况下你可以去3,如果你想等到第4个。
正如你在评论中问我Task.Run和statnew方法之间有什么区别 - :为此你可以查看这个问题:Regarding usage of Task.Start() , Task.Run() and Task.Factory.StartNew()
答案 2 :(得分:-1)
你应该只等待异步方法。要运行您不想等待的同步线程,可以使用胎面池中的新线程:
new Thread(() => DoSomething()).Start();
或
Task.Factory.SartNew(()=> DoSomething());
以下是帮助页面:https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspx
否则,在执行下一行之前,您必须完成对GetUserDetails
的调用。