C# 如何使用单个';等待任务。什么时候;?

C# 如何使用单个';等待任务。什么时候;?,c#,async-await,task-parallel-library,C#,Async Await,Task Parallel Library,我假设我必须使用Task.whalll在下面的代码中,但无法确定它是否应该正确实现 请帮忙 public async void UpdateData() { var month = (cbMonths.SelectedItem as MonthView).ID; var year = (cbYears.SelectedItem as YearView).ID; var deviceTypeID = (int

我假设我必须使用
Task.whalll
在下面的代码中,但无法确定它是否应该正确实现

请帮忙

 public async void UpdateData()
        {
            var month = (cbMonths.SelectedItem as MonthView).ID;
            var year = (cbYears.SelectedItem as YearView).ID;
            var deviceTypeID = (int)DeviceType;
            var calendar = await GetCalendar(month, year, deviceTypeID);
            var workTypes = await GetWorkTypes(); 

            if (calendar != null && workTypes != null) // Task.WhenAll ???
            {
                //...
            }
        }


 private async Task<List<WorkTypeItem>> GetWorkTypes()
        {
            try
            {
                HttpClient client = new HttpClient();

                var url = Properties.Settings.Default.ServerBaseUrl + @"/api/staff/WorkTypes";

                HttpResponseMessage response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)    // Check the response StatusCode
                {
                    var serSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };    
                    string responseBody = await response.Content.ReadAsStringAsync();

                    return JsonConvert.DeserializeObject<List<MSOCommon.WorkTypeItem>>(responseBody, serSettings); 
                }              
                else
                {
                    logger.Error(Properties.Resources.DATACannotGetWorkTypes);
                }
            }
            catch (Exception ex)
            {
                logger.Error(Properties.Resources.DATACannotGetWorkTypes + " " + ex.Message);
            }

            return null;
        }
public异步void UpdateData()
{
var month=(cbMonths.SelectedItem作为MonthView.ID;
var year=(cbYears.SelectedItem作为YearView).ID;
var deviceTypeID=(int)DeviceType;
var calendar=等待获取日历(月、年、设备类型ID);
var-workTypes=await-GetWorkTypes();
if(calendar!=null&&workTypes!=null)//Task.WhenAll???
{
//...
}
}
私有异步任务GetWorkTypes()
{
尝试
{
HttpClient=新的HttpClient();
var url=Properties.Settings.Default.ServerBaseUrl+@“/api/staff/WorkTypes”;
HttpResponseMessage response=wait client.GetAsync(url);
if(response.issucessStatusCode)//检查响应状态代码
{
var serSettings=new JsonSerializerSettings(){typenameholling=typenameholling.All};
string responseBody=wait response.Content.ReadAsStringAsync();
返回JsonConvert.DeserializeObject(responseBody,serSettings);
}              
其他的
{
logger.Error(Properties.Resources.DATACannotGetWorkTypes);
}
}
捕获(例外情况除外)
{
logger.Error(Properties.Resources.DATACannotGetWorkTypes+“”+ex.Message);
}
返回null;
}

如果希望两个任务同时执行,则不要等待方法。而是将它们的任务传递到变量中,并在
Task.whalll

public async Task UpdateData() {
    var month = (cbMonths.SelectedItem as MonthView).ID;
    var year = (cbYears.SelectedItem as YearView).ID;
    var deviceTypeID = (int)DeviceType;
    var task1 = GetCalendar(month, year, deviceTypeID);
    var task2 = GetWorkTypes(); 

    await Task.WhenAll(task1, task2);

    var calendar = task1.Result;
    var workTypes = task2.Result;
}
还要注意,您应该避免使用
异步void
方法

var calendarTask = GetCalendar(month, year, deviceTypeID);
var workTypesTask = GetWorkTypes(); 

Task.WaitAll(calendarTask, workTypesTask);
var calendar = await calendarTask;
var workTypes = await workTypesTask;

要回答@crazyGamer,您这样做的原因是为了两个任务可以同时运行。否则,在你开始第二项工作之前,你正在等待第一项任务。当然,如果他们相互依赖,那是件好事。否则,这将在MP系统上运行得更快。

@Dimi不要等待这些方法。将它们的任务传递到一个变量中,并在
Task中调用它们。如果我说的很幼稚,很抱歉,但是上面的代码为什么不起作用呢?由于该方法是
async
,并在每个异步调用上使用
wait
,因此
if(calendar!=null&&workTypes!=null)
将仅在前两条语句完成后执行。不是吗?不,我不认为有什么问题<代码>任务。当您有许多电话要打时,whalll
是另一种选择。请参阅中的这一行:“将等待运算符应用于异步方法中的任务,以在方法的执行中插入挂起点,直到等待的任务完成。”代码将以任何方式工作。区别在于它们的执行方式。在OP中,每个任务将一个接一个地执行。使用
任务。当所有
时,它们同时执行。@crazyGamer您指出
异步无效
是正确的+1。最好返回
任务
对象,因为在调用它时,您可以更好地控制执行。您不应该等待两次,这可以有效地使用此代码。在这种情况下不需要WaitAll。或者“抛弃”等待,改为访问
.Result
。@JohnySkovdal-来自msdn on
.Result
:“访问属性的get访问器会阻止调用线程,直到异步操作完成;这相当于调用Wait方法”(可以肯定的是,在这一点上使用
.Result
更为明确,但我不喜欢有副作用的属性,所以一般避免使用它)我的观点很简单,你已经在等待Task.WaitAll,如果你在相同的任务上再次使用wait,你还可以跳过这一行吗?