繁体   English   中英

在Sync方法中调用Async

[英]Calling Async in a Sync method

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

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行中应用await,希望大家能给我一些指导,让我再保持几年的精力。

您可以将方法标记为异步并等待它,也可以在返回的Task上调用.Wait()或.Result()。

我不知道如何将等待应用于Client.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关键字时冒起(在此示例中,在行字符串结果(...)处)
  • 建议命名将Task对象返回为MethodNameAsync的方法

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM