The basic usage of the .NET client library is as follows:

```c#
// Initialize a GoogleAdsConfig instance.
GoogleAdsConfig config = new GoogleAdsConfig()
{
    OAuth2Mode = OAuth2Flow.SERVICE_ACCOUNT,
    OAuth2SecretsJsonPath = "PATH_TO_CREDENTIALS_JSON",
    LoginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE"
};

// Initialize a GoogleAdsClient instance.
GoogleAdsClient client = new GoogleAdsClient(config);

// Create the required service.
CampaignServiceClient campaignService =
    client.GetService(Services.V26.CampaignService);

// Make calls to the service client.
```

## Initialize the client and services

To interact with the Google Ads API, first configure and instantiate a
`GoogleAdsClient`, and then use it to create the specific API service clients
you need.

### Create a `GoogleAdsClient` instance

The most important class in the Google Ads API .NET library is the `GoogleAdsClient`
class. It lets you create a pre-configured service client that can be used for
making API calls. To configure a `GoogleAdsClient` object, create a
`GoogleAdsConfig` object and set the required properties. Refer to the
[Configuration guide](https://developers.google.com/google-ads/api/docs/client-libs/dotnet/configuration.md.txt) to learn more.

```c#
// Initialize a GoogleAdsConfig instance.
GoogleAdsConfig config = new GoogleAdsConfig()
{
    OAuth2Mode = OAuth2Flow.SERVICE_ACCOUNT,
    OAuth2SecretsJsonPath = "PATH_TO_CREDENTIALS_JSON",
    LoginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE"
};

// Initialize a GoogleAdsClient instance.
GoogleAdsClient client = new GoogleAdsClient(config);

// Modify the GoogleAdsClient configuration afterwards if needed.
client.Config.LoginCustomerId = "INSERT_UPDATED_LOGIN_CUSTOMER_ID_HERE";
```

### Create a service

`GoogleAdsClient` provides a `GetService` method that can be used to create an
API service client.

```c#
CampaignServiceClient campaignService = client.GetService(
    Services.V26.CampaignService);
// Now make calls to CampaignService.
```

The library provides a `Services` class that enumerates all the supported API
versions (where minor releases such as `v26.1` use their major
version enum, `Services.V26`) and services. The
`GetService` method accepts these enumeration
objects as an argument when creating the service. For example, to create an
instance of `CampaignServiceClient` for version `V26` of
the Google Ads API, call the `GoogleAdsClient.GetService` method with
`Services.V26.CampaignService` as the argument, as shown
in the preceding example.

## Error handling

Not every API call succeeds. The server can return errors if your API calls
fail for some reason. It is important to capture API errors and handle them
appropriately.

A `GoogleAdsException` instance is thrown when an API error occurs. It contains
details to help you figure out what went wrong:


```
public void Run(GoogleAdsClient client, long customerId)
{
    // Get the GoogleAdsService.
    GoogleAdsServiceClient googleAdsService = client.GetService(
        Services.V26.GoogleAdsService);

    // Create a query that will retrieve all campaigns.
    string query = @"SELECT
                    campaign.id,
                    campaign.name,
                    campaign.network_settings.target_content_network
                FROM campaign
                ORDER BY campaign.id";

    try
    {
        // Issue a search request.
        googleAdsService.SearchStream(customerId.ToString(), query,
            delegate (SearchGoogleAdsStreamResponse resp)
            {
                foreach (GoogleAdsRow googleAdsRow in resp.Results)
                {
                    Console.WriteLine("Campaign with ID {0} and name '{1}' was found.",
                        googleAdsRow.Campaign.Id, googleAdsRow.Campaign.Name);
                }
            }
        );
    }
    catch (GoogleAdsException e)
    {
        Console.WriteLine("Failure:");
        Console.WriteLine($"Message: {e.Message}");
        Console.WriteLine($"Failure: {e.Failure}");
        Console.WriteLine($"Request ID: {e.RequestId}");
        throw;
    }
}
      
```

<br />

## Thread safety

Modifying the configuration state of a shared `GoogleAdsClient` instance across
multiple threads is not thread-safe, because configuration changes you make on
an instance in one thread can affect the services you create on other threads.
However, read-only operations like obtaining new service instances from an
unchanging `GoogleAdsClient` instance and making calls to multiple services in
parallel are thread-safe.

To isolate per-thread configuration changes, instantiate a separate
`GoogleAdsClient` per worker task or thread:

```c#
GoogleAdsClient client1 = new GoogleAdsClient();
GoogleAdsClient client2 = new GoogleAdsClient();

Task task1 = Task.Run(() => AddAdGroups(client1));
Task task2 = Task.Run(() => AddAdGroups(client2));

await Task.WhenAll(task1, task2);

public void AddAdGroups(GoogleAdsClient client)
{
    // Perform operations with client.
}
```

## Keep your application responsive

Google Ads API method calls can take a while to complete, depending on how large the
requests are. To keep your application responsive, follow these steps:

### Use the `Grpc.Core` library for legacy UI frameworks

If you are developing an application that targets .NET Framework and uses a
legacy UI technology such as ASP.NET Web Forms or WinForms, you can enable the
legacy `Grpc.Core` transport library as follows:

```c#
GoogleAdsConfig config = new GoogleAdsConfig();
config.UseGrpcCore = true;
GoogleAdsClient client = new GoogleAdsClient(config);
```

### Use asynchronous methods

You can use asynchronous methods to keep your application responsive. Here are a
couple of examples.

#### Retrieve the list of campaigns and populate a `ListView`

```c#
private async void OnRetrieveCampaignsButtonClick(object sender, EventArgs e)
{
    try
    {
        // Get the GoogleAdsService.
        GoogleAdsServiceClient googleAdsService = client.GetService(
            Services.V26.GoogleAdsService);

        // Create a query that will retrieve all campaigns.
        string query = @"SELECT
                        campaign.id,
                        campaign.name,
                        campaign.network_settings.target_content_network
                    FROM campaign
                    ORDER BY campaign.id";

        List<ListViewItem> items = new List<ListViewItem>();
        await googleAdsService.SearchStreamAsync(
            customerId.ToString(),
            query,
            (SearchGoogleAdsStreamResponse resp) =>
            {
                foreach (GoogleAdsRow googleAdsRow in resp.Results)
                {
                    ListViewItem item = new ListViewItem();
                    item.Text = googleAdsRow.Campaign.Id.ToString();
                    item.SubItems.Add(googleAdsRow.Campaign.Name);
                    items.Add(item);
                }
            }
        );
        listView1.Items.AddRange(items.ToArray());
    }
    catch (GoogleAdsException ex)
    {
        MessageBox.Show($"API Error: {ex.Message}");
    }
}
```

#### Update a campaign budget and display a message box alert

```c#
private async void OnUpdateBudgetButtonClick(object sender, EventArgs e)
{
    try
    {
        // Get the CampaignBudgetService.
        CampaignBudgetServiceClient budgetService = client.GetService(
            Services.V26.CampaignBudgetService);

        // Create the campaign budget.
        CampaignBudget budget = new CampaignBudget()
        {
            Name = "Interplanetary Cruise Budget #" +
                ExampleUtilities.GetRandomString(),
            DeliveryMethod = BudgetDeliveryMethod.Standard,
            AmountMicros = 500000
        };

        // Create the operation.
        CampaignBudgetOperation budgetOperation = new CampaignBudgetOperation()
        {
            Create = budget
        };

        // Create the campaign budget asynchronously.
        MutateCampaignBudgetsResponse response =
            await budgetService.MutateCampaignBudgetsAsync(
                customerId.ToString(),
                new CampaignBudgetOperation[] { budgetOperation });

        MessageBox.Show(response.Results[0].ResourceName);
    }
    catch (GoogleAdsException ex)
    {
        MessageBox.Show($"API Error: {ex.Message}");
    }
}
```