我有一個更新方法,獲取最後一個活動項目,並用新值克隆它,並將活動標誌設置爲true。我的問題是更新方法是由多個Web API方法調用的,所以最後一個活動項目並不總是相同的。我結束了多個活動項目和數據不一致。所以我想鏈接所有電話,以解決這個問題,但我不知道在哪裏start.`在c#中鏈接多個相同的方法調用#
[HttpPost]
[Route("Route2")]
[ValidateModel]
public async Task<HttpResponseMessage> Post(string contractReference, [FromBody] Family input)
{
return await CallPartialUpdate(contractReference, p => p.Family = input);
}
[HttpPost]
[Route("Route3")]
[ValidateModel]
public async Task<HttpResponseMessage> Post(string contractReference, [FromBody] Address input)
{
return await CallPartialUpdate(contractReference, p => p.Address = input);
}
private async Task<HttpResponseMessage> CallPartialUpdate(string reference, Item itemToUpdate)
{
try
{
var existingItem = _bContext.RetrieveLastActive(reference);
if (existingItem == null)
return Request.CreateResponse(HttpStatusCode.NotFound);
var newRecord = existingItem.Document.Clone();
newRecord.update(itemToUpdate);
newRecord.active = true;
await _bContext.PutDocumentAsync(newRecord, reference);
return Request.CreateResponse(HttpStatusCode.Created);
}
catch (System.Exception exception)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, exception.Message);
}
}`
基於@Asti答案我創建單元測試與觀察到的Rx但我仍然有數據矛盾中的最後一項,所以我如何得到這個工作,我如何獲得callPartialUpdate()的結果,謝謝
[TestFixture]
public class Concurrency
{
[Test]
public async Task Update_Should_Always_Change_Last_Item()
{
var observer = Observable.Timer(TimeSpan.FromMilliseconds(1));
var items = new List<Item>()
{
new Item() { FirstName = "AA", LastName = "BB" , IsActive = true },
new Item() { FirstName = "A", LastName = "A" , IsActive = false },
};
await Task.Run(() =>
{
Parallel.Invoke(async() => await observer.Select(item => Observable.FromAsync(ct => UpdateItem(items, new Item() { FirstName = "AAA" })))
.Concat(),
async() => await observer.Select(item => Observable.FromAsync(ct => UpdateItem(items, new Item() { LastName = "BBB" })))
.Concat());
});
var lastItem = items.Single(w => w.IsActive);
Assert.AreEqual("AAA", lastItem.FirstName);
Assert.AreEqual("BBB", lastItem.LastName);
}
public async Task<bool> UpdateItem(List<Item> items, Item itemToUpdate)
{
return await Task.Run(() => update(items, itemToUpdate));
}
private bool update(List<Item> items, Item itemToUpdate)
{
var lastItem = items.Single(w => w.IsActive == true);
lastItem.IsActive = false;
var newItem = new Item()
{
FirstName = string.IsNullOrEmpty(itemToUpdate.FirstName) ? lastItem.FirstName : itemToUpdate.FirstName,
LastName = string.IsNullOrEmpty(itemToUpdate.LastName) ? lastItem.LastName : itemToUpdate.LastName,
IsActive = true
};
items.Add(newItem);
return true;
}
}
您需要一個鎖 - 如果我們能夠看到您的代碼,它會更容易幫助。 – Hogan
@霍根,感謝您的評論,但與鎖會產生死鎖我想在更新行動中使用被動擴展訂閱,但我不知道如何實現它 – moyomeh
鎖只會生成一個死鎖,如果你做錯了。如果你做得對,它會解決你的問題。 – Hogan