在异步方法中调用时,方法是否必须是异步的?

时间:2017-12-01 17:35:14

标签: c# .net asynchronous

假设我有一个定义如下的方法:

public async Task CreateUser()
{
   await GetUserDetails();
   GetUserOrder();
}

private void GetUserDetails() {

private void GetUserOrder() {

方法GetUserDetails();GetUserOrder()是否必须async以避免UI阻止?

我不能await GetUserDetails()方法,因为它不是异步的。我怎样才能在c#中实现这一目标?我想确保一步一步地调用所有这些方法。

3 个答案:

答案 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的调用。