C# 是否从MainWindow后台工作程序在另一个类中运行HttpClient PostAsync?
前言:我是个业余爱好者,请原谅我的无知;-) 我正在尝试执行一个基于网络的多功能任务(在线天体测量板块解算),该任务位于我的主窗口之外的一个单独的类中。我希望在后台执行此操作以保持主窗口处于活动状态(用于在滚动日志文本框中记录消息)。C# 是否从MainWindow后台工作程序在另一个类中运行HttpClient PostAsync?,c#,C#,前言:我是个业余爱好者,请原谅我的无知;-) 我正在尝试执行一个基于网络的多功能任务(在线天体测量板块解算),该任务位于我的主窗口之外的一个单独的类中。我希望在后台执行此操作以保持主窗口处于活动状态(用于在滚动日志文本框中记录消息)。 在我的主窗口中,我称之为: public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { Astrometry ast = ne
在我的主窗口中,我称之为:
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Astrometry ast = new Astrometry();
ast.OnlineSolve(GlobalVariables.SolveImage);
}
在天体测量课程中,它停在等待的httpClient.PostAsync(。。。
返回到主窗口,没有其他事情发生
class Astrometry
{
public void OnlineSolve(string image)
{
GetSession(apikey);
}
private async void GetSession(string apikey)
{
...misc code
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpContent contentPost = new StringContent(input, Encoding.UTF8, "application/x-www-form-urlencoded");
using (var response = await httpClient.PostAsync(baseAddress, contentPost))
{
string responseData = await response.Content.ReadAsStringAsync();
...more stuff
}
}
我想知道这样做是不是不可能。。。
提前感谢!使用async/Wait时,必须确保始终传播任务
public async Task OnlineSolve(string image)
{
await GetSession(apikey).ConfigureAwait(false);
}
private async Task GetSession(string apikey)
{
...misc code
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpContent contentPost = new StringContent(input, Encoding.UTF8, "application/x-www-form-urlencoded");
using (var response = await httpClient.PostAsync(baseAddress, contentPost).ConfigureAwait(false))
{
string responseData = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
...more stuff
}
}
}
同样在工人身上:
public async void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Astrometry ast = new Astrometry();
await ast.OnlineSolve(GlobalVariables.SolveImage);
}
主要规则是不要中断等待链。一旦中断它,就失去了异步操作的跟踪,也失去了等待结果和处理任何错误的操作
还要注意的是,由于您使用的是纯异步I/O,因此一开始就不需要使用后台工作程序。只需直接从按钮单击处理程序或其他任何程序运行异步方法,您就可以了。如果您还需要做一些CPU工作,Task.run
是一个不错的选择。我甚至不确定后台是否可用worker处理将await
正确地编组回正确的线程(EDIT:,事实上,它没有;因此将BackgroundWorker
与await
一起使用实际上没有任何意义,这只是让人困惑——只需使用任务。运行进行CPU工作,运行await
进行异步I/O)
要记住的是await
基本上是一个神奇的返回
(类似于收益返回
,如果你曾经使用过的话)。一旦执行到达等待未完成任务的await
,方法return
就是一个任务
(如果可能的话)。这就是调用者重新获得流控制的点-如果在调用者中不使用wait
,则这就是调用者继续执行时的工作状态。有时,这是可取的-例如,在并行启动多个任务时。通常,您只想wait
所有异步方法非常感谢。非常有效,我采纳了你的建议,删除了后台工作人员。@Luaan:FYI,后台工作人员将在第一时间退出,并等待
。DoWork
将在线程池线程上恢复。我发现这种行为令人困惑(即,“提前”触发completed),所以我建议您使用Task。如果您需要,请在BGW上运行。在这种情况下,您当然不会这样做。@StephenCleary是的,我有点期待这样的事情会发生。它可以工作的唯一方法是使用自己的同步上下文,这在没有等待的情况下是毫无意义的。我将它添加到答案中。