C# 如何在运行另一个任务之前完成任务

C# 如何在运行另一个任务之前完成任务,c#,asp.net-web-api,task-parallel-library,async-await,C#,Asp.net Web Api,Task Parallel Library,Async Await,我正在使用Microsoft Web API 2.2客户端从API端点请求数据。在我得到数据后,我运行x个DoSomeWork。我想确保在运行DoSomeWork函数之前先加载数据 基于下面的代码,我期望得到以下输出 “开始做某事” “完成一些事情” “开始工作#1” “开始工作#2” 但是我得到了如下的结果 “开始做某事” “开始工作#1” “完成一些事情” “开始工作#2” static void Main() { 尝试 { Task getSomethingTask=Task.Factor

我正在使用Microsoft Web API 2.2客户端从API端点请求数据。在我得到数据后,我运行x个DoSomeWork。我想确保在运行DoSomeWork函数之前先加载数据

基于下面的代码,我期望得到以下输出

“开始做某事” “完成一些事情” “开始工作#1” “开始工作#2”

但是我得到了如下的结果 “开始做某事” “开始工作#1” “完成一些事情” “开始工作#2”

static void Main()
{
尝试
{
Task getSomethingTask=Task.Factory.StartNew(()=>GetSomething());
getSomethingTask.Wait();
任务[]任务=新任务[2]{
Task.Facotry.StartNew(()=>DoSomeWork(1)),
Task.Facotry.StartNew(()=>DoSomeWork(2))
};
Task.WaitAll(任务);
}
捕获(例外情况除外)
{
掷骰子;
}
}
静态异步任务GetSomething()
{
Console.WriteLine(“开始获取某物”);
尝试
{
HttpClient=新的HttpClient();
client.BaseAddress=新Uri(一些URL);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(新的MediaTypeWithQualityHeaderValue(“应用程序/json”);
HttpResponseMessage response=wait client.GetAsync(“api/v1/somethings”);
somethingList=wait response.Content.ReadAsAsync();
}
捕获(例外)
{
投掷;
}
Console.WriteLine(“用GetSomething完成”);
}
静态异步任务DoSomeWork(int workNumber)
{
Console.Writeline(“开始工作”#“+工作编号);
}

我相信
GetSomething任务
马上就要完成了,因为你没有等待
ing
GetSomething()

试试这个:

Task getSomethingTask = Task.Factory.StartNew(async () => await GetSomething());
或者简单地说:

GetSomething().Wait();

尽管我认为创建一个新线程并立即在主线程上等待结果并不会真正获得任何好处。

当您从线程调用
wait
时,您会将控制权交回其父线程

在这种情况下,这是您的违规行为:

HttpResponseMessage response = await client.GetAsync("api/v1/somethings");
一旦您这样做,您的
GetSomething
线程就会将控制权返回到
Main()
线程,这就是您看到执行
DoSomeWork
任务的原因

如果您在
GetSomething
中去掉那些
wait
调用,并用同步调用替换它们,您将获得所需的行为


有关更多信息,请参见此处的Microsoft异步编程指南(特别是第6步,其中谈到了
Wait
):

在执行异步编程(即,i/O绑定)时,您希望避免
开始新的
等待
,以及
WaitAll
。相反,对几乎所有逻辑使用
async
wait

由于这是一个控制台应用程序,您确实需要一个
等待
,以便主线程不会退出。这应该是整个应用程序中唯一的
Wait

static void Main()
{
  MainAsync().Wait();
}

static async Task MainAsync()
{
  await GetSomethingAsync();
  await Task.WhenAll(DoSomeWorkAsync(1), DoSomeWorkAsync(2));
}

static async Task GetSomethingAsync()
{
  Console.WriteLine("Starting GetSomething");
  HttpClient client = new HttpClient();
  ...
  HttpResponseMessage response = await client.GetAsync("api/v1/somethings");
  somethingList = await response.Content.ReadAsAsync<SomeObject>();
  Console.WriteLine("Done with GetSomething");
}

static async Task DoSomeWorkAsync(int workNumber)
{
  Console.Writeline("Start work#" + workNumber);
}
static void Main()
{
MainAsync().Wait();
}
静态异步任务mainsync()
{
等待GetSomethingAsync();
等待任务。WhenAll(DoSomeWorkAsync(1),DoSomeWorkAsync(2));
}
静态异步任务GetSomethingAsync()
{
Console.WriteLine(“开始获取某物”);
HttpClient=新的HttpClient();
...
HttpResponseMessage response=wait client.GetAsync(“api/v1/somethings”);
somethingList=wait response.Content.ReadAsAsync();
Console.WriteLine(“用GetSomething完成”);
}
静态异步任务DoSomeWorkAsync(int workNumber)
{
Console.Writeline(“开始工作”#“+工作编号);
}
你会发现我的建议很有帮助

static void Main()
{
  MainAsync().Wait();
}

static async Task MainAsync()
{
  await GetSomethingAsync();
  await Task.WhenAll(DoSomeWorkAsync(1), DoSomeWorkAsync(2));
}

static async Task GetSomethingAsync()
{
  Console.WriteLine("Starting GetSomething");
  HttpClient client = new HttpClient();
  ...
  HttpResponseMessage response = await client.GetAsync("api/v1/somethings");
  somethingList = await response.Content.ReadAsAsync<SomeObject>();
  Console.WriteLine("Done with GetSomething");
}

static async Task DoSomeWorkAsync(int workNumber)
{
  Console.Writeline("Start work#" + workNumber);
}