Cyc*_*eak 9 c# async-await dotnet-httpclient .net-standard-2.0
代码在 .NET Standard 2.0 中运行。我有一个构造函数调用一个方法,该方法将调用这样的 Azure 函数:
public ChatViewModel(IChatService chatService)
{
Task.Run(async () =>
{
if (!chatService.IsConnected)
{
await chatService.CreateConnection();
}
});
}
Run Code Online (Sandbox Code Playgroud)
方法是这样的:
public async Task CreateConnection()
{
await semaphoreSlim.WaitAsync();
if (httpClient == null)
{
httpClient = new HttpClient();
}
var result = await httpClient.GetStringAsync(uri);
var info = JsonConvert.DeserializeObject<Models.ConnectionInfo>(result);
//... some other code ...
semaphoreSlim.Release();
}
Run Code Online (Sandbox Code Playgroud)
代码停在
等待 httpClient.GetStringAsync(uri)
URI 是 100% 有效的,如果我将它复制并粘贴到浏览器中,我会得到我想要的 JSON。
打开 Fiddler 时,没有调用 URI。
编辑 源代码来自这个 Github 存储库:https : //github.com/PacktPublishing/Xamarin.Forms-Projects/tree/master/Chapter06-07/Chat/Chat
编辑 2 此代码正在运行:
static void Main(string[] args)
{
using (var httpClient = new HttpClient())
{
var a = httpClient.GetStringAsync(uri).GetAwaiter().GetResult();
}
}
Run Code Online (Sandbox Code Playgroud)
此代码不起作用:
static void Main(string[] args)
{
Task.Run(async() => {
using (var httpClient = new HttpClient())
{
var a = await httpClient.GetStringAsync(uri);
}
});
}
Run Code Online (Sandbox Code Playgroud)
Arm*_*our 12
我猜您的问题是因为您可能在控制台应用程序(或 Windows 服务)中运行它而没有任何代码片段来保持您的应用程序活动。
此代码不起作用:
static void Main(string[] args)
{
Task.Run(async() => {
using (var httpClient = new HttpClient())
{
var a = await httpClient.GetStringAsync(uri);
}
});
}
Run Code Online (Sandbox Code Playgroud)
这段代码显然不起作用,因为Task.Run创建了一个后台线程和Main方法,然后立即完成(并且分别导致您的任务终止)。只需Console.ReadKey()在Main方法末尾添加以使其保持活动状态,您将看到一切正常:
static void Main(string[] args)
{
Task.Run(async() => {
using (var httpClient = new HttpClient())
{
var a = await httpClient.GetStringAsync(uri);
}
});
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是为MainC# 8 中引入的方法使用新的异步入口点:
static async Task Main(string[] args)
{
using (var httpClient = new HttpClient())
{
var a = await httpClient.GetStringAsync(uri);
}
}
Run Code Online (Sandbox Code Playgroud)
这可能是在构造函数中调用异步代码的问题。.GetAwaiter().GetResult()如果您真的想在那时运行异步代码,您应该使用:
public ChatViewModel(IChatService chatService)
{
Task.Run(async () =>
{
if (!chatService.IsConnected)
{
await chatService.CreateConnection();
}
}).GetAwaiter().GetResult();
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢一个单独的异步 Init 方法,该方法将在创建实例后调用。另一种可能的解决方案是创建一个异步 GetInfo() 方法:
private async Task<Models.ConnectionInfo> GetInfo(){
if(_info != null)
return _info;
await semaphoreSlim.WaitAsync();
try{
if(_info != null)
return _info;
if (httpClient == null)
{
httpClient = new HttpClient();
}
var result = await httpClient.GetStringAsync(uri);
var info = JsonConvert.DeserializeObject<Models.ConnectionInfo>(result);
//... some other code ...
return _info = info;
} finally {
semaphoreSlim.Release();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以调用该方法来获取您的信息,并且代码只会在第一次使用时运行。
| 归档时间: |
|
| 查看次数: |
1653 次 |
| 最近记录: |