适用于 .NET 的 Amazon 异步 API - Amazon SDK for .NET(版本 3)
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本内容重点介绍.NET FrameworkASP.NET 4.x。它涵盖了视窗和视觉工作室。

使用.NET 内核或者ASP.NET Core? 转至版本 3.5 或更高版本的Amazon SDK for .NET。除了 Windows 和视觉工作室之外,它还涵盖跨平台的开发。

HelloAmazon.NET 社区!请分享您的经验,帮助我们改进Amazon SDK for .NET及其学习资源进行调查。此项调查大约需要 10 分钟能完成。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

适用于 .NET 的 Amazon 异步 API

适用于 .NET Framework 4.5、Windows Store 和 Windows Phone 8 的异步 API

Amazon SDK for .NET使用面向 .NET Framework 版本 4.5、Windows Store 和 Windows Phone 8 的新的基于任务的异步模式。您可以将asyncawait关键字执行和管理对所有Amazon产品无阻塞。

要了解有关基于任务的异步模式的更多信息,请参阅基于任务的异步模式 (TAP)在医生。微软网上。要查看 TAP 如何在Amazon SDK for .NET,对于 .NET Framework 4.5 项目和 .NET Core 项目,请参阅最新版本的文档

适用于 .NET Framework 3.5 的异步 API

Amazon SDK for .NET支持由 .NET 客户端类公开的大多数方法调用的异步版本。异步方法允许您调用Amazon服务,而不会让您的代码阻止来自服务的响应。例如,您可以发出请求以将数据写入 Amazon S3 或 DynamoDB 中,然后让您的代码在Amazon处理请求。

异步请求方法的语法

发出异步请求的过程包含两个阶段Amazon服务。第一个阶段是为请求调用 Begin 方法。此方法将启动异步操作。相应的 End 方法将检索来自服务的响应,并提供处理操作期间可能已发生的异常的机会。

注意

不需要调用 End 方法。假定未遇到错误,则异步操作将会完成,无论是否调用 End

Begin 方法语法

除了接受请求对象参数(例如 PutItemRequest)之外,异步 Begin 方法还接受两个参数:回调函数和状态对象。而不是返回服务响应对象Begin方法返回类型为IAsyncResult。对于此类型的定义,请转至微软文档

同步方法

PutItemResponse PutItem( PutItemRequest putItemRequest )

异步方法

IAsyncResult BeginPutItem( GetSessionTokenRequest getSessionTokenRequest, {AsyncCallback callback}, {Object state} )

AsyncCallback 回调

在异步操作完成时,将调用回调函数。在调用此函数时,它将收到一个 IAsyncResult 类型的参数。此回调函数具有以下签名。

void Callback(IAsyncResult asyncResult)

对象状态

第三个参数 (即 state) 是一个用户定义的对象,它将作为 asyncResult 参数的 AsyncState 属性 (即 asyncResult.AsyncState) 提供给回调函数。

调用模式

  • 传递回调函数和状态对象。

  • 传递回调函数,但为状态对象传递 null。

  • 为回调函数和状态对象传递 null。

本主题对于这些模式中的每个模式均提供了一个示例。

使用 IAsyncResult.AsyncWaitHandle

在某些情况下,调用 Begin 方法的代码可能需要启用它调用的另一个方法,以便等待异步操作完成。在这些情况下,它可以将方法传递给由 WaitHandle 返回值的 IAsyncResult.AsyncWaitHandle 属性返回的 IAsyncResult。之后,此方法将通过对此 WaitOne 调用 WaitHandle 来等待异步操作完成。

Examples

有关完整的代码示例,请参阅下文中的完整示例或者在 GitHub 上查看。

以下所有代码段都采用下面的初始化代码。

public static void TestPutObjectAsync(string bucket) { // Create a client AmazonS3Client client = new AmazonS3Client(); PutObjectResponse response; IAsyncResult asyncResult; // // Create a PutObject request object using the supplied bucket name. // PutObjectRequest request = new PutObjectRequest { BucketName = bucket, Key = "Item0-Synchronous", ContentBody = "Put S3 object synchronously." };

未指定回调

以下示例代码调用 BeginPutObject,执行某些工作,然后调用 EndPutObject 以检索服务响应。对 EndPutObject 的调用包含在 try 块中,以便捕获操作期间可能已引发的任何异常。

asyncResult = client.BeginPutObject(request, null, null); while (!asyncResult.IsCompleted) { // // Do some work here // } try { response = client.EndPutObject(asyncResult); } catch (AmazonS3Exception s3Exception) { Console.WriteLine("Caught exception calling EndPutObject:"); Console.WriteLine(s3Exception); }

简单回调

此示例假定已定义以下回调函数。

public static void SimpleCallback(IAsyncResult asyncResult) { Console.WriteLine("Finished PutObject operation with simple callback."); Console.WriteLine("--------------------------------------------------"); Console.WriteLine("asyncResult.IsCompleted: {0}\n\n", asyncResult.IsCompleted.ToString()); }

以下代码行调用 BeginPutObject 并指定上述回调函数。在 PutObject 操作完成后,将调用该回调函数。对 BeginPutObject 的调用将为 null 参数指定 state,因为简单回调函数不访问 AsyncState 参数的 asyncResult 属性。调用代码和回调函数都不调用 EndPutObject。因此,服务响应实际上将被丢弃,并且将忽略操作期间发生的任何异常。

asyncResult = client.BeginPutObject(request, SimpleCallback, null);

使用客户端的回调

此示例假定已定义以下回调函数。

public static void CallbackWithClient(IAsyncResult asyncResult) { try { AmazonS3Client s3Client = (AmazonS3Client)asyncResult.AsyncState; PutObjectResponse response = s3Client.EndPutObject(asyncResult); Console.WriteLine("Finished PutObject operation with client callback. Service Version: {0}", s3Client.Config.ServiceVersion); Console.WriteLine("--------------------------------------------------"); Console.WriteLine("Service Response:"); Console.WriteLine("-----------------"); Console.WriteLine("Request ID: {0}\n\n", response.ResponseMetadata.RequestId); } catch (AmazonS3Exception s3Exception) { Console.WriteLine("Caught exception calling EndPutObject:"); Console.WriteLine(s3Exception); } }

以下代码行调用 BeginPutObject 并指定上述回调函数。在 PutObject 操作完成后,将调用该回调函数。在本示例中,对BeginPutObject指定 Amazon S3 客户端对象state参数。回调函数使用客户端调用 EndPutObject 方法来检索服务器响应。由于在回调调用 EndPutObject 时将收到操作期间发生的任何异常,因此,该调用放置在 try 块中。

asyncResult = client.BeginPutObject(request_client, CallbackWithClient, client);

使用状态对象的回调

此示例假定已定义以下类和回调函数。

class ClientState { public AmazonS3Client Client { get; set; } public DateTime Start { get; set; } }
public static void CallbackWithState(IAsyncResult asyncResult) { try { ClientState state = asyncResult.AsyncState as ClientState; AmazonS3Client s3Client = (AmazonS3Client)state.Client; PutObjectResponse response = state.Client.EndPutObject(asyncResult); Console.WriteLine("Finished PutObject operation with state callback that started at {0}", state.Start.ToString()); Console.WriteLine("--------------------------------------------------"); Console.WriteLine("Service Response:"); Console.WriteLine("-----------------"); Console.WriteLine("Request ID: {0}\n\n", response.ResponseMetadata.RequestId); } catch (AmazonS3Exception s3Exception) { Console.WriteLine("Caught exception calling EndPutObject:"); Console.WriteLine(s3Exception); } }

以下代码行调用 BeginPutObject 并指定上述回调函数。在 PutObject 操作完成后,将调用该回调函数。在此示例中,对 BeginPutObject 的调用将为 state 参数指定前面定义的 ClientState 类的实例。此类将嵌入 Amazon S3 客户端以及BeginPutObject将调用。回调函数使用 Amazon S3 客户端对象调用EndPutObject方法来检索服务器响应。回调还将提取操作的开始时间,并使用它输出完成异步操作所需的时间。

与上述示例中一样,由于调用 EndPutObject 时会接收到操作期间发生的异常,因此,此调用放置在 try 块中。

asyncResult = client.BeginPutObject(request_state, CallbackWithState, new ClientState { Client = client, Start = DateTime.Now });

完整示例

以下代码示例演示在调用异步请求方法时可使用的模式。

using System; using System.Threading; using Amazon.S3; using Amazon.S3.Model; namespace async_aws_net { class ClientState { public AmazonS3Client Client { get; set; } public DateTime Start { get; set; } } class Program { // // Function Main(). // Parse the command line and call the worker function. // public static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("You must supply the name of an existing Amazon S3 bucket."); return; } TestPutObjectAsync(args[0]); } // // Function SimpleCallback(). // A very simple callback function. // public static void SimpleCallback(IAsyncResult asyncResult) { Console.WriteLine("Finished PutObject operation with simple callback."); Console.WriteLine("--------------------------------------------------"); Console.WriteLine("asyncResult.IsCompleted: {0}\n\n", asyncResult.IsCompleted.ToString()); } // // Function CallbackWithClient(). // A callback function that provides access to a given S3 client. // public static void CallbackWithClient(IAsyncResult asyncResult) { try { AmazonS3Client s3Client = (AmazonS3Client)asyncResult.AsyncState; PutObjectResponse response = s3Client.EndPutObject(asyncResult); Console.WriteLine("Finished PutObject operation with client callback. Service Version: {0}", s3Client.Config.ServiceVersion); Console.WriteLine("--------------------------------------------------"); Console.WriteLine("Service Response:"); Console.WriteLine("-----------------"); Console.WriteLine("Request ID: {0}\n\n", response.ResponseMetadata.RequestId); } catch (AmazonS3Exception s3Exception) { Console.WriteLine("Caught exception calling EndPutObject:"); Console.WriteLine(s3Exception); } } // // Function CallbackWithState(). // A callback function that provides access to a given S3 client as well as state information. // public static void CallbackWithState(IAsyncResult asyncResult) { try { ClientState state = asyncResult.AsyncState as ClientState; AmazonS3Client s3Client = (AmazonS3Client)state.Client; PutObjectResponse response = state.Client.EndPutObject(asyncResult); Console.WriteLine("Finished PutObject operation with state callback that started at {0}", state.Start.ToString()); Console.WriteLine("--------------------------------------------------"); Console.WriteLine("Service Response:"); Console.WriteLine("-----------------"); Console.WriteLine("Request ID: {0}\n\n", response.ResponseMetadata.RequestId); } catch (AmazonS3Exception s3Exception) { Console.WriteLine("Caught exception calling EndPutObject:"); Console.WriteLine(s3Exception); } } // // Function TestPutObjectAsync(). // Test synchronous and asynchronous variations of PutObject(). // public static void TestPutObjectAsync(string bucket) { // Create a client AmazonS3Client client = new AmazonS3Client(); PutObjectResponse response; IAsyncResult asyncResult; // // Create a PutObject request object using the supplied bucket name. // PutObjectRequest request = new PutObjectRequest { BucketName = bucket, Key = "Item0-Synchronous", ContentBody = "Put S3 object synchronously." }; // // Perform a synchronous PutObject operation. // Console.WriteLine("-------------------------------------------------------------------------------"); Console.WriteLine("Performing synchronous PutObject operation for {0}.", request.Key); response = client.PutObject(request); Console.WriteLine("Finished PutObject operation for {0}.", request.Key); Console.WriteLine("Service Response:"); Console.WriteLine("-----------------"); Console.WriteLine("Request ID: {0}", response.ResponseMetadata.RequestId); Console.Write("\n"); // // Perform an async PutObject operation and wait for the response. // // (Re-use the existing PutObject request object since it isn't being used for another async request.) // request.Key = "Item1-Async-wait"; request.ContentBody = "Put S3 object asynchronously; wait for response."; Console.WriteLine("-------------------------------------------------------------------------------"); Console.WriteLine("Performing async PutObject operation and waiting for response (Key: {0}).", request.Key); asyncResult = client.BeginPutObject(request, null, null); while (!asyncResult.IsCompleted) { // // Do some work here // } try { response = client.EndPutObject(asyncResult); } catch (AmazonS3Exception s3Exception) { Console.WriteLine("Caught exception calling EndPutObject:"); Console.WriteLine(s3Exception); } Console.WriteLine("Finished Async PutObject operation for {0}.", request.Key); Console.WriteLine("Service Response:"); Console.WriteLine("-----------------"); Console.WriteLine("Request ID: {0}\n", response.ResponseMetadata.RequestId); Console.WriteLine("-------------------------------------------------------------------------------"); Console.WriteLine("Performing the following async PutObject operations:"); Console.WriteLine("\"simple callback\", \"callback with client\", and \"callback with state\"...\n"); // // Perform an async PutObject operation with a simple callback. // // (Re-use the existing PutObject request object since it isn't being used for another async request.) // request.Key = "Item2-Async-simple"; request.ContentBody = "Put S3 object asynchronously; use simple callback."; Console.WriteLine("PutObject with simple callback (Key: {0}).", request.Key); asyncResult = client.BeginPutObject(request, SimpleCallback, null); // // Perform an async PutObject operation with a client callback. // // Create a PutObject request object for this call using the supplied bucket name. // PutObjectRequest request_client = new PutObjectRequest { BucketName = bucket, Key = "Item3-Async-client", ContentBody = "Put S3 object asynchronously; use callback with client." }; Console.WriteLine("PutObject with client callback (Key: {0}).", request_client.Key); asyncResult = client.BeginPutObject(request_client, CallbackWithClient, client); // // Perform an async PutObject operation with a state callback. // // Create a PutObject request object for this call using the supplied bucket name. // PutObjectRequest request_state = new PutObjectRequest { BucketName = bucket, Key = "Item3-Async-state", ContentBody = "Put S3 object asynchronously; use callback with state." }; Console.WriteLine("PutObject with state callback (Key: {0}).\n", request_state.Key); asyncResult = client.BeginPutObject(request_state, CallbackWithState, new ClientState { Client = client, Start = DateTime.Now }); // // Finished with async calls. Wait a bit for them to finish. // Thread.Sleep(TimeSpan.FromSeconds(5)); } } }

您也可以在 GitHub 上查看。

另请参阅