Здравствуйте, Vladek, Вы писали:
S>>Воспроизвести можно, но нужно постараться.
V> Гораздо вероятнее, что код в будущем изменится и неявное предположение, что параллельный код меняет разные части объекта, станет ложным.
О, подход из серии "мы закладываемся на то, что этот объект никто не будет использовать"? Одобряю.
Если серьёзно, члены типа или поддерживают использование в нескольких потоках, или нет. Большинство instance members в BCL — нет, это соглашение по умолчанию.
Если вы решили отступить от этого контракта, ответственность "спроектировать тип так, чтобы при его использовании не возникало косяков" целиком и полностью ваша
Здравствуйте, e.thrash, Вы писали:
ET>каждый из методов вычисляет и меняет независимые друг от друга данные объекта Car.
ET>Насколько опасным будет код если эти два метода распаллелить в Task.ContinueWhenAll ?
ET>Нужна ли в данном случае синхронизация?
Если цель распараллелить длительные вычисления отдельных свойств, то лучше так и сделать, а сливать их и обновлять объект уже можно после того, как они вычислены.
Вот псевдокод:
async Task Calculate(Car car)
{
var priceTask = CalculatePriceAsync(inputForPrice);
var useTimeTask = CalculateUseTime(inputForUseTime);
await Task.WhenAll(priceTask, useTimeTask);
car.Price = priceTask.Result;
car.UseTime = useTimeTask.Result;
}
Как уже заметили ниже, поскольку вычисляются два разных аспекта, то менять объек Car из разных потоков можно. Но ведь это может измениться (да, это размышления на будущее). Но поскольку разделить вычисления новых значений от изменения объекта car — задача тривиальная и в любом случае лучше разделяет ответственности в коде, то проще поступить так с самого начала: выделить вычисления в отдельные методы, запустить вычисления параллельно, а затем "заджоиниться" и обновить объект, когда обе операции будут завершены.