在Sync方法中调用Async

时间:2016-09-03 03:03:22

标签: c# amazon-web-services asynchronous amazon-s3 async-await

我已经阅读了很长一段时间的例子了,但不幸的是我无法将解决方案应用到我正在使用的代码中。一些简单的事实/各种信息:

1)我是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);
        }
    });
}

我不知道如何将等待应用到Client.ListObjectsAsync行,我希望你们都能给我一些指导,让我保持头发多年。

3 个答案:

答案 0 :(得分:1)

您可以将方法标记为异步并等待它,或者您可以在您给予的任务上调用.Wait()或.Result()。

答案 1 :(得分:1)

  

我不知道如何将await应用于Client.ListObjectsAsync行

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

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

只要执行此操作,Visual Studio就会给您一个错误。仔细查看错误消息,因为它会告诉您完全下一步要做什么(使用InitiateSearch标记async并将其返回类型更改为Task) :

public async Task InitiateSearchAsync()

(添加Async后缀以跟随the common pattern)也是一个好主意。

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

答案 2 :(得分:0)

我假设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关键字:“等待”任务。将此关键字放在任务之前,以异步方式等待它完成
  • 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关键字时冒泡(在此示例中为行字符串结果(...))
  • 建议命名将Task对象作为MethodNameAsync
  • 返回的方法

有关此内容的更多信息,请查看http://blog.stephencleary.com/2012/02/async-and-await.html