等待方法导致应用程序退出
Awaiting method causes application to exit
我试图在网上查找对此问题的答案,但没有找到任何答案。
我的这个方法看起来不错,并且似乎遵循异步 post 调用在 c# 中工作的一般流程。
private static async Task<HttpResponseMessage> GetGeocodingAsync(string URL, string JSONQuery)
{
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage r = await client.PostAsync(URL, new StringContent(JSONQuery, Encoding.UTF8, "application/json")))
{
return r;
}
}
}
public Task<HttpResponseMessage> GetGeocoding(string TTURL, string JSONQuery)
{
return GetGeocodingAsync(TTURL, JSONQuery);
}
当我检查语法和 IDE 时,但是当我 运行 应用程序时,它到达第 5 行,然后应用程序仅以代码 0 (以代码 0 (0x0).).
退出
我已经做了很多网络研究,但找不到这个问题的答案。我在这里错过了一些基本的东西吗?
我知道我必须为实际的 post 部分使用 private static async
,然后我可以从非静态非异步方法调用此方法,并在我的主要 class 我可以这样处理得到的响应:
Task<HttpResponseMessage> x = TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery);
我正在尝试使用 POST 发送一些 JSON 格式的数据,通过解析它来检查响应,并将响应下拉到 POST.
我正在使用 TomTom Batch API
欢迎提出任何想法或建议。
我认为您的问题是您使用 async / await 和一般任务的方式。
这一行
Task<HttpResponseMessage> x = TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery);
... 需要使用异步方法并在任务上调用 await 或 .Result。 x 不是任务的结果,而是任务本身。任务只是一个托管线程,对吗?你正在做的是分配 x 线程可以这么说,而不是线程完成的结果(......只是它不是一个线程,它是一个任务,但无论如何)。
为了让 x 成为任务的结果,您需要做类似...
var x = await TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery);
或
var x = TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery).Result;
要指出的另一件事是,您的 private static GetGeocodingAsync
方法与 public GetGeoCoding
方法相同。您可以将 .Result
放在 public 方法 return 行中,它会起作用。或者您可以只删除它并将 GetGeocodingAsync 方法与 .Result 一起使用或等待它。
无论如何,关键是您没有正确使用任务,我认为对于任务是什么/任务是什么以及如何正确地正常使用它或使用异步等待只是有点混淆。也没什么大不了的。只需修复代码以正确调用它,它就会正常工作(例如抛出错误或不抛出错误。)
如果这是一个简单的控制台exe,那么主线程中不完整的await
通常会终止exe。这是因为 await
returns 到调用代码,如果你退出 Main()
,你的线程就会退出。如果所有非后台线程退出:您的应用程序退出。
在最新的 C# 版本中,您可以:
async static Task Main() {...}
而不是:
static void Main() {...}
它会为您正确运行。或者,您可以执行以下操作:
static void Main() {
Main2().GetAwaiter().GetResult();
}
async static Task Main2() {...} // your code here
另一种可能是您在后台线程中遇到未等待的异常,因为您没有 await
-ing 所有任务。线程讨厌错误,线程顶部的未处理异常 会终止您的应用程序。如果这是问题所在:await
你的任务,或者如果你真的不关心成功的话,添加一个忽略错误的延续。例如:
static void FireAndForget(this Task task)
{
if (task.IsCompleted) return;
task.ContinueWith(t =>
{
try
{ // show it that we checked
GC.KeepAlive(t.Exception);
} catch { }
}, TaskContinuationOptions.OnlyOnFaulted);
}
我试图在网上查找对此问题的答案,但没有找到任何答案。
我的这个方法看起来不错,并且似乎遵循异步 post 调用在 c# 中工作的一般流程。
private static async Task<HttpResponseMessage> GetGeocodingAsync(string URL, string JSONQuery)
{
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage r = await client.PostAsync(URL, new StringContent(JSONQuery, Encoding.UTF8, "application/json")))
{
return r;
}
}
}
public Task<HttpResponseMessage> GetGeocoding(string TTURL, string JSONQuery)
{
return GetGeocodingAsync(TTURL, JSONQuery);
}
当我检查语法和 IDE 时,但是当我 运行 应用程序时,它到达第 5 行,然后应用程序仅以代码 0 (以代码 0 (0x0).).
退出我已经做了很多网络研究,但找不到这个问题的答案。我在这里错过了一些基本的东西吗?
我知道我必须为实际的 post 部分使用 private static async
,然后我可以从非静态非异步方法调用此方法,并在我的主要 class 我可以这样处理得到的响应:
Task<HttpResponseMessage> x = TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery);
我正在尝试使用 POST 发送一些 JSON 格式的数据,通过解析它来检查响应,并将响应下拉到 POST.
我正在使用 TomTom Batch API
欢迎提出任何想法或建议。
我认为您的问题是您使用 async / await 和一般任务的方式。
这一行
Task<HttpResponseMessage> x = TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery);
... 需要使用异步方法并在任务上调用 await 或 .Result。 x 不是任务的结果,而是任务本身。任务只是一个托管线程,对吗?你正在做的是分配 x 线程可以这么说,而不是线程完成的结果(......只是它不是一个线程,它是一个任务,但无论如何)。
为了让 x 成为任务的结果,您需要做类似...
var x = await TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery);
或
var x = TTConnect.GetGeocoding(TTConnect.GetTTConnectionURL(),JSONQuery).Result;
要指出的另一件事是,您的 private static GetGeocodingAsync
方法与 public GetGeoCoding
方法相同。您可以将 .Result
放在 public 方法 return 行中,它会起作用。或者您可以只删除它并将 GetGeocodingAsync 方法与 .Result 一起使用或等待它。
无论如何,关键是您没有正确使用任务,我认为对于任务是什么/任务是什么以及如何正确地正常使用它或使用异步等待只是有点混淆。也没什么大不了的。只需修复代码以正确调用它,它就会正常工作(例如抛出错误或不抛出错误。)
如果这是一个简单的控制台exe,那么主线程中不完整的await
通常会终止exe。这是因为 await
returns 到调用代码,如果你退出 Main()
,你的线程就会退出。如果所有非后台线程退出:您的应用程序退出。
在最新的 C# 版本中,您可以:
async static Task Main() {...}
而不是:
static void Main() {...}
它会为您正确运行。或者,您可以执行以下操作:
static void Main() {
Main2().GetAwaiter().GetResult();
}
async static Task Main2() {...} // your code here
另一种可能是您在后台线程中遇到未等待的异常,因为您没有 await
-ing 所有任务。线程讨厌错误,线程顶部的未处理异常 会终止您的应用程序。如果这是问题所在:await
你的任务,或者如果你真的不关心成功的话,添加一个忽略错误的延续。例如:
static void FireAndForget(this Task task)
{
if (task.IsCompleted) return;
task.ContinueWith(t =>
{
try
{ // show it that we checked
GC.KeepAlive(t.Exception);
} catch { }
}, TaskContinuationOptions.OnlyOnFaulted);
}