Асинхронный метод отправки ответа обратно в Main - PullRequest
0 голосов
/ 10 января 2019

Я реализовал мыльный клиент, используя метод 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
  }

МЕТОД ASYNC

 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 голосов
/ 11 января 2019

Если вы планируете выполнять много асинхронных операций в консольном приложении, я рекомендую использовать такой шаблон 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 (в противном случае вы столкнетесь с ошибкой модели синхронизации и получите взаимоблокировку).

0 голосов
/ 11 января 2019

В консольном приложении до 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
}
0 голосов
/ 10 января 2019

В 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()}");
  }
}
...