

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Pemrograman asinkron menggunakan AWS SDK untuk C\$1\$1
<a name="async-methods"></a>

## Metode SDK asinkron
<a name="asynchronous-sdk-methods"></a>

Untuk banyak metode, SDK for C\$1\$1 menyediakan versi sinkron dan asinkron. Sebuah metode asinkron jika menyertakan `Async` sufiks dalam namanya. Misalnya, metode `PutObject` Amazon S3 sinkron, sementara `PutObjectAsync` asinkron.

Seperti semua operasi asinkron, metode SDK asinkron kembali sebelum tugas utamanya selesai. Misalnya, `PutObjectAsync` metode kembali sebelum selesai mengunggah file ke bucket Amazon S3. Sementara operasi unggahan berlanjut, aplikasi dapat melakukan operasi lain, termasuk memanggil metode asinkron lainnya. Aplikasi diberitahu bahwa operasi asinkron telah selesai ketika fungsi callback terkait dipanggil.

Bagian berikut menjelaskan contoh kode yang menunjukkan pemanggilan metode `PutObjectAsync` asinkron. Setiap bagian berfokus pada bagian-bagian individual dari [seluruh file sumber](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object_async.cpp) contoh.

## Memanggil metode asinkron SDK
<a name="calling-sdk-asynchronous-methods"></a>

Secara umum, versi asinkron dari metode SDK menerima argumen berikut.
+ Referensi ke objek tipe Permintaan yang sama dengan rekan sinkron.
+ Referensi ke fungsi callback handler respon. Fungsi callback ini dipanggil saat operasi asinkron selesai. Salah satu argumen berisi hasil operasi.
+ Opsional `shared_ptr` untuk suatu `AsyncCallerContext` objek. Objek diteruskan ke callback handler respon. Ini termasuk properti UUID yang dapat digunakan untuk meneruskan informasi teks ke callback.

`uploadFileAsync`Metode yang ditunjukkan di bawah ini mengatur dan memanggil metode Amazon `PutObjectAsync` S3 SDK untuk mengunggah file secara asinkron ke bucket Amazon S3.

Fungsi menerima referensi ke `S3Client` objek dan `PutObjectRequest` objek. Ia menerima mereka dari fungsi utama karena kita perlu memastikan bahwa objek-objek ini ada sepanjang durasi panggilan asinkron.

A `shared_ptr` ke `AsyncCallerContext` objek dialokasikan. `UUID`Properti diatur ke nama objek Amazon S3. Untuk tujuan demonstrasi, callback pengendali respons mengakses properti dan mengeluarkan nilainya.

Panggilan untuk `PutObjectAsync` menyertakan argumen referensi ke fungsi callback handler respons. `uploadFileAsyncFinished` Fungsi callback ini diperiksa secara lebih rinci di bagian berikutnya.

```
bool AwsDoc::S3::uploadFileAsync(const Aws::S3::S3Client &s3Client,
                                Aws::S3::Model::PutObjectRequest &request,
                                const Aws::String &bucketName,
                                const Aws::String &fileName) {
    request.SetBucket(bucketName);
    request.SetKey(fileName);

    const std::shared_ptr<Aws::IOStream> input_data =
            Aws::MakeShared<Aws::FStream>("SampleAllocationTag",
                                          fileName.c_str(),
                                          std::ios_base::in | std::ios_base::binary);

    if (!*input_data) {
        std::cerr << "Error: unable to open file " << fileName << std::endl;
        return false;
    }

    request.SetBody(input_data);

    // Create and configure the context for the asynchronous put object request.
    std::shared_ptr<Aws::Client::AsyncCallerContext> context =
            Aws::MakeShared<Aws::Client::AsyncCallerContext>("PutObjectAllocationTag");
    context->SetUUID(fileName);

    // Make the asynchronous put object call. Queue the request into a 
    // thread executor and call the uploadFileAsyncFinished function when the
    // operation has finished. 
    s3Client.PutObjectAsync(request, uploadFileAsyncFinished, context);

    return true;
}
```

Sumber daya untuk operasi asinkron harus ada sampai operasi selesai. Misalnya, klien dan objek permintaan harus ada sampai aplikasi menerima pemberitahuan bahwa operasi selesai. Aplikasi itu sendiri tidak dapat dihentikan sampai operasi asinkron selesai.

Untuk alasan ini, `uploadFileAsync` metode menerima referensi ke `S3Client` dan `PutObjectRequest` objek alih-alih membuatnya dalam `uploadFileAsync` metode dan menyimpannya dalam variabel lokal. 

Dalam contoh, `PutObjectAsync` metode kembali ke pemanggil segera setelah memulai operasi asinkron, memungkinkan rantai panggilan untuk melakukan tugas tambahan saat operasi upload sedang berlangsung. 

Jika klien disimpan dalam variabel lokal dalam `uploadFileAsync` metode, itu akan keluar dari cakupan ketika metode dikembalikan. Namun, objek klien harus terus ada sampai operasi asinkron selesai.

## Pemberitahuan Penyelesaian Operasi Asinkron
<a name="notification-of-the-completion-of-an-asynchronous-operation"></a>

Ketika operasi asinkron selesai, fungsi callback handler respon aplikasi dipanggil. Pemberitahuan ini mencakup hasil operasi. Hasilnya terkandung dalam kelas tipe Outcome yang sama yang dikembalikan oleh rekan sinkron metode. Dalam contoh kode, hasilnya ada di `PutObjectOutcome` objek.

Fungsi callback handler respon contoh ditunjukkan di bawah `uploadFileAsyncFinished` ini. Ini memeriksa apakah operasi asinkron berhasil atau gagal. Ini menggunakan a `std::condition_variable` untuk memberi tahu utas aplikasi bahwa operasi async telah selesai.

```
// A mutex is a synchronization primitive that can be used to protect shared
// data from being simultaneously accessed by multiple threads.
std::mutex AwsDoc::S3::upload_mutex;

// A condition_variable is a synchronization primitive that can be used to
// block a thread, or to block multiple threads at the same time.
// The thread is blocked until another thread both modifies a shared
// variable (the condition) and notifies the condition_variable.
std::condition_variable AwsDoc::S3::upload_variable;
```

```
void uploadFileAsyncFinished(const Aws::S3::S3Client *s3Client,
                            const Aws::S3::Model::PutObjectRequest &request,
                            const Aws::S3::Model::PutObjectOutcome &outcome,
                            const std::shared_ptr<const Aws::Client::AsyncCallerContext> &context) {
    if (outcome.IsSuccess()) {
        std::cout << "Success: uploadFileAsyncFinished: Finished uploading '"
                  << context->GetUUID() << "'." << std::endl;
    } else {
        std::cerr << "Error: uploadFileAsyncFinished: " <<
                  outcome.GetError().GetMessage() << std::endl;
    }

    // Unblock the thread that is waiting for this function to complete.
    AwsDoc::S3::upload_variable.notify_one();
}
```

Dengan operasi asinkron selesai, sumber daya yang terkait dengannya dapat dilepaskan. Aplikasi juga dapat dihentikan jika diinginkan.

Kode berikut menunjukkan bagaimana `uploadFileAsync` dan `uploadFileAsyncFinished` metode yang digunakan oleh aplikasi.

Aplikasi mengalokasikan `PutObjectRequest` objek `S3Client` dan sehingga mereka terus ada sampai operasi asinkron selesai. Setelah menelepon`uploadFileAsync`, aplikasi dapat melakukan operasi apa pun yang diinginkannya. Untuk mempermudah, contoh menggunakan `std::mutex` dan menunggu `std::condition_variable` hingga callback penangan respons memberi tahu bahwa operasi unggahan telah selesai.

```
int main(int argc, char* argv[])
{
    if (argc != 3)
    {
        std::cout << R"(
Usage:
    run_put_object_async <file_name> <bucket_name>
Where:
    file_name - The name of the file to upload.
    bucket_name - The name of the bucket to upload the object to.
)" << std::endl;
        return 1;
    }

    const Aws::SDKOptions options;
    Aws::InitAPI(options);
    {
        const Aws::String fileName = argv[1];
        const Aws::String bucketName = argv[2];

        // A unique_lock is a general-purpose mutex ownership wrapper allowing
        // deferred locking, time-constrained attempts at locking, recursive
        // locking, transfer of lock ownership, and use with
        // condition variables.
        std::unique_lock<std::mutex> lock(AwsDoc::S3::upload_mutex);

        // Create and configure the Amazon S3 client.
        // This client must be declared here, as this client must exist
        // until the put object operation finishes.
        const Aws::S3::S3ClientConfiguration config;
        // Optional: Set to the AWS Region in which the bucket was created (overrides config file).
        // config.region = "us-east-1";

        const Aws::S3::S3Client s3Client(config);

        // Create the request object.
        // This request object must be declared here, because the object must exist
        // until the put object operation finishes.
        Aws::S3::Model::PutObjectRequest request;

        AwsDoc::S3::uploadFileAsync(s3Client, request, bucketName, fileName);

        std::cout << "main: Waiting for file upload attempt..." <<
                  std::endl << std::endl;

        // While the put object operation attempt is in progress,
        // you can perform other tasks.
        // This example simply blocks until the put object operation
        // attempt finishes.
        AwsDoc::S3::upload_variable.wait(lock);

        std::cout << std::endl << "main: File upload attempt completed."
                  << std::endl;
    }
    Aws::ShutdownAPI(options);

    return 0;
}
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object_async.cpp) di Github.