如何最好地将异步任务返回给调用者
本文关键字:返回 调用者 任务 异步 何最好 | 更新日期: 2023-09-27 18:25:14
我将在Cassandra中插入行,尽管我的问题是关于Cassandra,但一般来说如何最好地使用异步API。简而言之,我在C#代码中为一行生成一个id,并异步插入,并希望将id返回给调用者。下面的示例代码显示了我迄今为止所尝试的内容,所有这些都有效,但哪一个最好?是否有替代方案或更好的解决方案?
比如说,我有一些课,所有的卡桑德拉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);
}
这似乎也有效,这意味着调用者等待的任务将包括插入,因此应该确保插入已经完成。
我有没有遗漏或误解什么?
await
没有阻塞,因此您的语句在技术上是不准确的。但我相信你的意思是"它不会继续执行",这是正确的。
创建一个全新的状态机
是的,但是很便宜。如果我计算正确的话,这里的await+async
负责4个小对象的分配。这并没有那么重要。特别地,由于高昂的数据库调用,它在噪声中消失了。
您的尝试2不可能如您所认识到的那样成功。
尝试3有效,但代码质量较差。首选1。