在Sync方法中调用Async

本文关键字:调用 Async 方法 Sync | 更新日期: 2023-09-27 18:05:21

我已经阅读示例很长时间了,但不幸的是,我一直无法将解决方案应用于我正在使用的代码。一些快速事实/各种信息:

我是c#新手

2)下面发布的代码是根据Amazon Web Services(主要是股票)修改的

3)代码的目的是将服务器信息与离线已经下载的信息进行比较,并创建一个需要下载文件的列表。这个片段是从服务器端生成的列表,AWS的唯一选项是调用异步,但我需要在继续之前完成这个。

public void InitiateSearch()
{
    UnityInitializer.AttachToGameObject(this.gameObject);
    //these are the access key and secret access key for credentials
    BasicAWSCredentials credentials = new BasicAWSCredentials("secret key", "very secret key");
    AmazonS3Config S3Config = new AmazonS3Config()
    {
        ServiceURL = ("url"),
        RegionEndpoint = RegionEndpoint.blahblah
    };
    //Setting the client to be used in the call below
    AmazonS3Client Client = new AmazonS3Client(credentials, S3Config);
    var request = new ListObjectsRequest()
    {
        BucketName = "thebucket"
    };
    Client.ListObjectsAsync(request, (responseObject) =>
    {
        if (responseObject.Exception == null)
        {
            responseObject.Response.S3Objects.ForEach((o) =>
            {
                int StartCut = o.Key.IndexOf(SearchType) - 11;
                if (SearchType == o.Key.Substring(o.Key.IndexOf(SearchType), SearchType.Length))
                {
                    if (ZipCode == o.Key.Substring(StartCut + 12 + SearchType.Length, 5))
                    {
                        AWSFileList.Add(o.Key + ", " + o.LastModified);
                    }
                }
            }
            );
        }
        else
        {
            Debug.Log(responseObject.Exception);
        }
    });
}

我不知道如何应用等待到客户端。ListObjectsAsync line,我希望你们都能给我一些指导,让我的头发再保持几年。

在Sync方法中调用Async

你可以将你的方法标记为async并等待它,或者你可以在你返回的任务上调用。wait()或。result()。

我不知道如何应用等待到客户端。ListObjectsAsync行

你可能只是把await放在它前面:

await Client.ListObjectsAsync(request, (responseObject) => ...

一旦你这么做了,Visual Studio就会给你一个错误。仔细查看错误消息,因为它准确地告诉您下一步该做什么(将InitiateSearch标记为async并将其返回类型更改为Task):

public async Task InitiateSearchAsync()

(添加Async后缀以遵循通用模式也是一个好主意)。

接下来,在调用InitiateSearchAsync的地方添加await,依此类推。

我假设Client.ListObjectsAsync返回Task对象,因此针对您的特定问题的解决方案是:

public async void InitiateSearch()
{
    //code
    var collection = await Client.ListObjectsAsync(request, (responseObject) =>
    {
        //code
    });
    foreach (var item in collection)
    {
        //do stuff with item
    }
}

变量result现在将被对象填充。您可能希望将InitiateSearch()的返回类型设置为Task,以便您也可以await它。

await InitiateSearch(); //like this

如果此方法是某种类型的事件处理程序(例如通过单击按钮调用),则可以继续使用void作为返回类型。

async-await文档中未发布部分的简单介绍:

使用async-await需要三个条件:

  • Task对象:该对象由异步执行的方法返回。它允许你控制方法的执行。
  • await关键字:"等待"任务。将此关键字放在Task之前以异步等待它完成
  • async关键字:所有使用await关键字的方法必须被标记为async

一个演示关键字

用法的小示例
public async Task DoStuffAsync()
{
    var result = await DownloadFromWebpageAsync(); //calls method and waits till execution finished
    var task = WriteTextAsync(@"temp.txt", result); //starts saving the string to a file, continues execution right await
    Debug.Write("this is executed parallel with WriteTextAsync!"); //executed parallel with WriteTextAsync!
    await task; //wait for WriteTextAsync to finish execution
}
private async Task<string> DownloadFromWebpageAsync()
{
    using (var client = new WebClient())
    {
        return await client.DownloadStringTaskAsync(new Uri("http://stackoverflow.com"));
    }
}
private async Task WriteTextAsync(string filePath, string text)
{
    byte[] encodedText = Encoding.Unicode.GetBytes(text);
    using (FileStream sourceStream = new FileStream(filePath, FileMode.Append))
    {
        await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
    }
} 

注意事项:

  • 您可以使用Task指定异步操作的返回值。await关键字等待方法执行完成,并返回字符串。
  • Task对象包含方法执行的状态,它可以作为任何其他变量使用。
  • 如果一个异常被抛出(例如由WebClient),它会在第一次使用await关键字时冒泡(在这个例子中在行字符串result(…))
  • 建议将返回Task对象的方法命名为MethodNameAsync

有关这方面的更多信息,请查看http://blog.stephencleary.com/2012/02/async-and-await.html。