2015-12-01 58 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

相關問題