彗星式 API 消耗 Async/Await
Comet-Style API Consumption with Async/Await
我正在尝试从您连接到的 Comet 样式 HTTP API 读取它并不断推送事件。我希望它在启动后在后台 运行,但是我的 Async/Await 是错误的,它冻结了我的 UI,我不知道为什么。
private async void button1_Click(object sender, EventArgs e)
{
await Task.Run((Func<Task>)PushEventReader);
}
public async Task PushEventReader()
{
var uri = "url.to/api";
var client = new WebClient();
client.OpenReadCompleted += async (sender, e) =>
{
using (var reader = new StreamReader(e.Result))
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
Console.WriteLine(line);
}
}
};
await client.OpenReadTaskAsync(new Uri(uri));
}
如果您的按钮单击事件除了在后台启动作业之外没有任何其他作用,那么与 async
进行异步处理是没有意义的,等待 Task.Run
也没有意义,因为您不是在那之后做任何事情。您可以像这样简单地点击按钮:
private void button1_Click(object sender, EventArgs e)
{
Task.Run(async () => await PushEventReader());
}
Task.Run
会将您传递给它的任何工作排队到 ThreadPool 上的 运行,这将有效地使其在后台 运行。
额外: 您正在使用的 WebClient
是非托管资源(您会注意到,因为它实现了 IDisposable
接口)并且它在 using
块中使用它们是一个很好的做法,它将为您处理处理:
public async Task PushEventReader()
{
var uri = "url.to/api";
using (var client = new WebClient())
{
client.OpenReadCompleted += async (sender, e) =>
{
using (var reader = new StreamReader(e.Result))
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
Console.WriteLine(line);
}
}
};
await client.OpenReadTaskAsync(new Uri(uri));
}
}
我正在尝试从您连接到的 Comet 样式 HTTP API 读取它并不断推送事件。我希望它在启动后在后台 运行,但是我的 Async/Await 是错误的,它冻结了我的 UI,我不知道为什么。
private async void button1_Click(object sender, EventArgs e)
{
await Task.Run((Func<Task>)PushEventReader);
}
public async Task PushEventReader()
{
var uri = "url.to/api";
var client = new WebClient();
client.OpenReadCompleted += async (sender, e) =>
{
using (var reader = new StreamReader(e.Result))
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
Console.WriteLine(line);
}
}
};
await client.OpenReadTaskAsync(new Uri(uri));
}
如果您的按钮单击事件除了在后台启动作业之外没有任何其他作用,那么与 async
进行异步处理是没有意义的,等待 Task.Run
也没有意义,因为您不是在那之后做任何事情。您可以像这样简单地点击按钮:
private void button1_Click(object sender, EventArgs e)
{
Task.Run(async () => await PushEventReader());
}
Task.Run
会将您传递给它的任何工作排队到 ThreadPool 上的 运行,这将有效地使其在后台 运行。
额外: 您正在使用的 WebClient
是非托管资源(您会注意到,因为它实现了 IDisposable
接口)并且它在 using
块中使用它们是一个很好的做法,它将为您处理处理:
public async Task PushEventReader()
{
var uri = "url.to/api";
using (var client = new WebClient())
{
client.OpenReadCompleted += async (sender, e) =>
{
using (var reader = new StreamReader(e.Result))
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
Console.WriteLine(line);
}
}
};
await client.OpenReadTaskAsync(new Uri(uri));
}
}