У меня есть метод обновления, который принимает последний активный элемент и клонирует его с новыми значениями и устанавливает активный флаг в true. Моя проблема в том, что метод update вызывается несколькими методами 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