如何最好地将异步任务返回给调用者

时间:2015-12-01 11:06:01

标签: c# asynchronous async-await

我正在向Cassandra插入行,虽然我的问题是关于Cassandra但是如何最好地使用异步API。简而言之,我为C#代码中的一行生成一个id,并异步执行插入并希望将id返回给调用者。下面的示例代码显示了我到目前为止所尝试的内容,所有这些都有效,但哪个最好?有替代方案或更好的解决方案吗?

说我有一些课程和所有Cassandra gubbins设置。这同样可以是我正在将类序列化的文件;这不是卡桑德拉的问题。

class MyClass
{
    public Guid Id { get; set; }
    public string Text { get; set; }
}

ISession cassandraSession;
PreparedStatement preparedStatement;

我的第一次尝试是使用async+await

async Task<Guid> Insert(MyClass someObject)
{
    someObject.Id = TimeUuid.NewId();

    BoundStatement insert = preparedStatement.Bind(someObject.Id, someObject.Text);

    await cassandraSession.ExecuteAsync(insert);

    return someObject.Id;
}

经过一些研究,我的理解是次优的,因为它会阻塞await并创建一个全新的状态机等。

接下来我尝试了这个:

Task<Guid> Insert(MyClass someObject)
{
    someObject.Id = TimeUuid.NewId();

    BoundStatement insert = preparedStatement.Bind(someObject.Id, someObject.Text);

    cassandraSession.ExecuteAsync(insert);

    return Task.FromResult(someObject.Id);
}

似乎没问题,没有阻止,但调用者是否可以在插入完成之前收到id和查询而没有找到该行?我尝试了延续:

Task<Guid> Insert(MyClass someObject)
{
    someObject.Id = TimeUuid.NewId();

    BoundStatement insert = preparedStatement.Bind(someObject.Id, someObject.Text);

    return cassandraSession
        .ExecuteAsync(insert)
        .ContinueWith(t => someObject.Id);
}

这也似乎有效并且意味着调用者等待的任务将包括插入,因此应确保插入已完成。

我错过了什么或误解了什么吗?

1 个答案:

答案 0 :(得分:1)

await没有阻止,因此您的陈述在技术上不准确。但我相信你的意思是&#34;它不会继续执行&#34;这是正确的。

  

创建一个全新的状态机

是的,但它很便宜。如果我正确计算,await+async这里负责4个小对象分配。那不是那么重要。特别是由于非常昂贵的数据库调用,它会在噪音中消失。

你的尝试2没有机会像你认出的那样工作。

尝试3个工作,但代码质量较差。首选1。