异步方法将响应发送回 Main
Async method sending response back to Main
我已经使用异步方法实现了一个 soap 客户端。我希望此方法 return 我从 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
}
}
在 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()}");
}
}
如果您计划在控制台应用程序中执行大量异步操作,我建议使用这种 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
中的代码(否则您将 运行与同步模型发生冲突并陷入僵局。
在 C# 7.0 之前的控制台应用程序中,可以像这样简单地实现它:
public static void Main()
{
string result = TEXT().Result;
Console.WriteLine(result);
}
在这种情况下TEXT
可以被认为是一种常用的方法,returnsTask<string>
,所以它的结果在Result
属性中可用。你不需要和服务员、结果等打交道。
同时,您不能在大多数类型的应用程序(WinForms、WPF、ASP.NET 等)中执行此操作,在这种情况下,您将不得不在所有应用程序中使用 async/await :
public async Task SomeMethod()
{
string result = await TEXT();
// ... do something with result
}
我已经使用异步方法实现了一个 soap 客户端。我希望此方法 return 我从 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
}
}
在 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()}");
}
}
如果您计划在控制台应用程序中执行大量异步操作,我建议使用这种 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
中的代码(否则您将 运行与同步模型发生冲突并陷入僵局。
在 C# 7.0 之前的控制台应用程序中,可以像这样简单地实现它:
public static void Main()
{
string result = TEXT().Result;
Console.WriteLine(result);
}
在这种情况下TEXT
可以被认为是一种常用的方法,returnsTask<string>
,所以它的结果在Result
属性中可用。你不需要和服务员、结果等打交道。
同时,您不能在大多数类型的应用程序(WinForms、WPF、ASP.NET 等)中执行此操作,在这种情况下,您将不得不在所有应用程序中使用 async/await :
public async Task SomeMethod()
{
string result = await TEXT();
// ... do something with result
}