异步方法将响应发送回Main

时间:2019-01-10 20:50:06

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

我已经使用Async方法实现了一个肥皂客户端。我希望该方法将我从API服务器获得的字符串值返回到主线程或另一个方法(无论调用哪个方法)。我该怎么做:

主要线程

 static void Main(string[] args)
 {

  TEXT().GetAwaiter().OnCompleted(() => { Console.WriteLine("finished"); });
  Console.ReadKey();

 // if I do it like this
 //  var test =  TEXT().GetAwaiter().OnCompleted(() => { Console.WriteLine("finished"); });
 // it gives me error: Cannot assign void to an implicitly-typed local variable
  }

异步方法

 public static async Task<string> TEXT()
 {
     Uri uri = new Uri("http://myaddress");
     HttpClient hc = new HttpClient();
     hc.DefaultRequestHeaders.Add("SOAPAction", "Some Action");
     var xmlStr = "SoapContent"; //not displayed here for simplicity
   var content = new StringContent(xmlStr, Encoding.UTF8, "text/xml");


  using (HttpResponseMessage response = await hc.PostAsync(uri, content))
  {
   var soapResponse = await response.Content.ReadAsStringAsync();
   string value = await response.Content.ReadAsStringAsync();
   return value; //how do I get this back to the main thread or any other method
  }
 }

3 个答案:

答案 0 :(得分:1)

如果您打算在控制台应用程序中执行大量异步操作,建议您使用这种MainAsync模式:

static public void Main(string[] args) //Entry point
{
    MainAsync(args).GetAwaiter().GetResult();
}

static public Task MainAsync(string[] args) //Async entry point
{
    await TEXT();
    Console.WriteLine("finished"); 
}

如果升级到C#7.1或更高版本,则可以删除Main方法并使用async main

或者,如果您曾经将此代码迁移到ASP.NET或WinForms应用程序,则可以忽略Main并在MainAsync中迁移代码(否则,您将违反同步模型并陷入僵局)。

答案 1 :(得分:1)

在C#7.0之前的控制台应用程序中,可以这样简单地实现:

public static void Main()
{
    string result = TEXT().Result;
    Console.WriteLine(result);
}

在这种情况下,可以将TEXT视为通常的方法,该方法返回Task<string>,因此其结果在Result属性中可用。您无需将服务员,结果等弄乱。

同时,您不能在大多数类型的应用程序(WinForms,WPF,ASP.NET等)中执行此操作,在这种情况下,您将必须在所有应用程序中使用async / await:

public async Task SomeMethod()
{
    string result = await TEXT();
    // ... do something with result
}

答案 2 :(得分:0)

在C#7.0+中,您可以使用async Task Main

static async Task Main(string[] args)
{
    var result =  TEXT().ConfigureAwait(false)
    Console.ReadKey();
}

对于较旧版本的C#

public static void Main(string[] args)
{
  try
  {
    TEST().GetAwaiter().GetResult();
  }
  catch (Exception ex)
  {
    WriteLine($"There was an exception: {ex.ToString()}");
  }
}