我正在向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);
}
这也似乎有效并且意味着调用者等待的任务将包括插入,因此应确保插入已完成。
我错过了什么或误解了什么吗?
答案 0 :(得分:1)
await
没有阻止,因此您的陈述在技术上不准确。但我相信你的意思是&#34;它不会继续执行&#34;这是正确的。
创建一个全新的状态机
是的,但它很便宜。如果我正确计算,await+async
这里负责4个小对象分配。那不是那么重要。特别是由于非常昂贵的数据库调用,它会在噪音中消失。
你的尝试2没有机会像你认出的那样工作。
尝试3个工作,但代码质量较差。首选1。