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是的,我有点期待这样的事情会发生。它可以工作的唯一方法是使用自己的同步上下文,这在没有等待的情况下是毫无意义的。我将它添加到答案中。