Why can't I debug code in an async method?

Because you are not awaiting your GetDataAsync method. When the first await is reached the thread is returned to the caller. Since you are not waiting for the completion of the task, your console application exits and your breakpoint is not reached. You will also need to update the GetDataAsync method to return a Task rather than void. You cannot await void. You should avoid using async void for anything other than the event handler.

protected static IMongoClient _client;
protected static IMongoDatabase _database;

static void Main(string[] args)
{
    _client = new MongoClient();
    _database = _client.GetDatabase("test");

    GetDataAsync().Wait(); 
    // Will block the calling thread but you don't have any other solution in a console application
}

private static async Task GetDataAsync() //method added by me.
{
    int x = await GetData();
}

private static async Task<int> GetData()
{
    var collection = _database.GetCollection<BsonDocument>("restaurants");
    var filter = new BsonDocument();
    var count = 0;
    Func<int> task = () => count; //added by me.
    var result = new Task<int>(task); //added by me.
    using (var cursor = await collection.FindAsync(filter)) //Debugger immediately exits here, goes back to main() and then terminates. 
    {
        while (await cursor.MoveNextAsync())
        {
            var batch = cursor.Current;
            foreach (var document in batch)
            {
                // process document
                count++;
            }
        }
    }

    return count; //added by me
}

I' not so good with async dev and had a similar problem, however I was kicking off the async method in Main like:

Task.Run(async () => await GetDataAsync());

I think the Garbage Collector was disposing of the anonymous method as nothing had a reference to it anymore. Using Fabien's .Wait() allowed me to step through the program and debug. I am using netcore 2.1 with vs2017