【问题标题】:How to create chaining tasks如何创建链接任务
【发布时间】:2018-10-20 16:04:20
【问题描述】:

我想用 for schedule 创建一个链接逻辑。

  1. 每 1 小时获取一次访问令牌。
  2. 如果访问令牌获取成功,获取版本
  3. 但如果 version.HasNextVersion 为 false,访问令牌将继续。

    public async Task<string> GetAccessToken(){
      /// getting token from server as async.
    }
    
    public async Task<string> GetVersions(string token){
        // Web request as async
        var version = await GetVersionsFromServer(token); 
    
       // if there are any other version after this version, I will get the next
        if(version.HasNextVersion) 
           await GetVersions();
    }
    
    string Main(){
    
     var accessToken = GetAccessToken().Wait();
    
     var version =  GetVersions(string token).Wait();
    
    }
    

我是异步操作和任务库的新手。这可能吗?

【问题讨论】:

  • await 已经链接了任务。它不会使任何东西异步运行。它等待已经异步操作完成,然后在异步操作之后立即继续执行代码,即链接它
  • 顺便说一句,在 C# 7.2 中,您可以定义 async Task Main() 方法并避免 .Wait() 调用。在以前的版本中,创建一个单独的方法,其中包含需要async 的任何内容,并且只使用一次.Wait()

标签: c# async-await task-parallel-library


【解决方案1】:

await 已经链接了这些任务。它不会使任何东西异步运行。它等待已经异步操作完成,然后在异步操作之后继续执行代码。

如果实际问题是how do I await in Main,在C# 7.1 中你可以有一个async Task Main() 签名,例如:

public static async Task Main(string[] args)
{

   var accessToken = await GetAccessToken();
   var version =  await GetVersions(string token);
}

如果您拥有带有最新更新之一的 Visual Studio 2017,您只需从“项目属性”、“构建”页面更改您的语言版本。可以从页面底部的“高级”按钮访问语言选项。

这个有详细描述herehere

在以前的版本中,您必须将所有异步代码提取到一个单独的方法中,并且只使用一次.Wait()

public static void Main(string[] args)
{
    InnerMain(args).Wait();
}

private static async Task InnerMain(string[] args)
{
   var accessToken = await GetAccessToken();
   var version =  await GetVersions(string token);
}

【讨论】:

    【解决方案2】:

    正确的方式(除了入口点之外一直异步):

    public async Task<string> GetAccessToken(){
        return "token";
    }
    
    public async Task<string> GetVersions(string token){
        var version = await GetVersionsFromServer(token); 
    
        if(version.HasNextVersion) 
           version = await GetVersions();
    
       // you need to return something!
       return version;
    }
    
    private async Task DoWork() {
      var accessToken = await GetAccessToken();
      var version =  await GetVersions(accessToken);
    }
    
    string Main(){
     DoWork().Wait();
    }
    

    否则,您可以在 Task 上使用 .Result 而不是 .Wait() 来阻止并等待结果。注意线程锁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      相关资源
      最近更新 更多