2015-12-01 55 views
0

虽然我的问题是关于Cassandra,但是如何最好地使用异步API,我将行插入到Cassandra中。简而言之,我为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); 
} 

硒EMS是好的,没有阻塞,但是调用者可以在插入完成之前收到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

你说:“我的理解是这是次优的,因为它会阻止等待”。这不是真的。你真的测试过这个看看它是否阻塞了吗? –

+0

你如何使用'Insert'方法? “Insert”方法的调用者是异步的吗? –

+0

你的中间一个看起来很糟糕 - 'ExecuteAsync'返回的是可以等待的东西,但你忽略了它。 –

回答

1

await不阻止,因此您的声明在技术上不准确。但我相信你的意思是“它不会继续执行”,这是正确的。

创造一个全新的状态机

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

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

尝试3的作品,但代码质量较差。首选1.

+0

谢谢。出于兴趣,1和3之间有什么区别。为什么3更糟糕? – batwad

+0

1是自然代码。3更复杂。代码越多,情况越糟糕。 – usr

相关问题