如何在异步方法中等待等待完成所有执行?

时间:2016-11-03 08:06:16

标签: c# async-await

对于以下代码,我调用async void方法。

<Project ToolsVersion="4.0" DefaultTargets="RunUnitTests" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

  <!-- Falls Eigenschaften nicht gesetzt -> Release & Any CPU als default-->
  <PropertyGroup>
    <!-- ... -->
  </PropertyGroup>

  <ItemGroup>
    <!-- ... -->
  </ItemGroup>

  <!-- All the stuff go into my main folder -->
  <Target Name="Init" DependsOnTargets="Clean">
    <MakeDir Directories="@(BuildArtifacts)" />
  </Target>

  <!-- delete my main folder -->
  <Target Name="Clean">
    <RemoveDir Directories="@(BuildArtifactsDir)" />
  </Target>

  <!-- delete NUnit-Files -->
  <Target Name="CleanAfter">
    <RemoveDir Directories="@(NunitDir)" />
  </Target>

  <Target Name="Compile" DependsOnTargets="Init">
    <MSBuild Projects="@(SolutionFile)" 
    Targets="Rebuild" 
    Properties="OutDir=%(BuildArtifactsDir.FullPath);
    Configuration=$(Configuration);
    Platform=$(BuildPlatform)" />
  </Target>

  <Target Name="RunUnitTests" DependsOnTargets="Compile">
         <Exec Command='"@(NUnitConsole)" "@(UnitTestsDLL)" --result=console-test.xml --work=BuildArtifacts' />
         <CallTarget Targets="CleanAfter" />
  </Target>

</Project>

以下代码为 public void LoadSystemDetails(int clientId) { DataSystem.Name = "Salesforce System"; DataSystem.Description = ""; GetAllFields(clientId); } 方法

GetAllFields

我打电话给 public async void GetAllFields(int clientId) { this.DataSystem.SystemTables = new List<DataSystemTable>(); using (var forceClient = await ConnectToSalesforceByOAuth(clientId)) { var SalesForceTable = new DataSystemTable { TableName = "Contact" }; DataSystem.SystemTables.Add(SalesForceTable); var contact = forceClient.DescribeAsync<SalesforceObject>("Contact"); var tableFields = new List<DataSystemField>(); foreach (var con in contact.Result.Fields) { tableFields.Add(new DataSystemField { ColumnName = con.Name, }); } SalesForceTable.EissSyncSystemFields = tableFields; } 如下。

callbackScript

此处 callbackScript.AppendLine(string.Format("var destinationSystem ={0};", JsonConvert.SerializeObject(this.DestinationSystem, Formatting.Indented))); 正在调用DestinationSystem。与LoadSystemDetails

一样

DestinationSystem.LoadSystemDetails(clientId)行在using (var forceClient = await ConnectToSalesforceByOAuth(clientId))执行时执行。所以callbackScript没有任何价值。但它有SystemTablesName

所以我需要等Description完成LoadSystemDetails

我是怎么做的。请帮帮我。 感谢。

2 个答案:

答案 0 :(得分:7)

如果您需要LoadSystemDetails等待GetAllFields,则此处存在以下两个问题:

  • 您正在从同步上下文中调用异步方法
  • GetAllFields是异步无效,这意味着火与忘。你永远无法等待它完成。

解决方案: 首先,如果您需要等待结果或结束,切勿使用async void。请使用async Task代替 其次,将LoadSystemDetails转换为异步方法,然后等待GetAllFields(应返回Task),或使用GetAllFields(clientId).Wait()

有关async / await的更多信息,请查看本文:https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

答案 1 :(得分:0)

正如@netchkin已经说过:永远不要使用- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *identifier = @"Cell"; StudentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath]; if (cell == nil) { cell = [[StudentTableViewCell alloc] init]; } if (_btnCancel.hidden == NO) { TeacherInfo *courseStudent = studentQuitArray[indexPath.row]; if ([studentDetail containsObject:courseStudent]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; else { cell.accessoryType = UITableViewCellAccessoryNone; } } else { cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } return cell; } 。使用-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell* cellCheck = [tableView cellForRowAtIndexPath:indexPath]; NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; if (_btnCancel.hidden == NO) { if (cellCheck.accessoryType == UITableViewCellAccessoryNone) { cellCheck.accessoryType = UITableViewCellAccessoryCheckmark; TeacherInfo *courseStudent = studentQuitArray[indexPath.row]; [dict setObject:courseStudent.id_user forKey:@"student_id"]; [studentDetail addObject:dict]; } else { cellCheck.accessoryType = UITableViewCellAccessoryNone; [studentDetail removeObject: studentQuitArray[indexPath.row]]; } } } 。您不必自己返回async void,仍然可以使用async Task