I need to use the lock construction, and edit the following methods to execute in parallel:
public void Withdraw(int amountToWithdraw) { if (amountToWithdraw <= 0) { throw new ArgumentException("The amount should be greater than 0."); } if (amountToWithdraw > MaxAmountPerTransaction) { throw new ArgumentException($"The value {amountToWithdraw} exceeds transaction limit: {MaxAmountPerTransaction}."); } if (amountToWithdraw > Amount) { throw new ArgumentException("Insufficient funds."); } WithdrawAndEmulateTransactionDelay(amountToWithdraw); } Here is the result
private readonly object balanceLock = new object(); public void Withdraw(int amountToWithdraw) { if (amountToWithdraw <= 0) { throw new ArgumentException("The amount should be greater than 0."); } if (amountToWithdraw > MaxAmountPerTransaction) { throw new ArgumentException($"The value {amountToWithdraw} exceeds transaction limit: {MaxAmountPerTransaction}."); } if (amountToWithdraw > Amount) { throw new ArgumentException("Insufficient funds."); } lock (balanceLock) { WithdrawAndEmulateTransactionDelay(amountToWithdraw); } } This is a description of the method WithdrawAndEmulateTransactionDelay which shouldn't be changed
private void WithdrawAndEmulateTransactionDelay(int amountToWithdraw) { Thread.Sleep(1000); Amount -= amountToWithdraw; } However, the unit test failed. Where is the mistake in my code?
ArgumentOutRangeExceptionis better (more readable and exact) thanArgumentExceptionin the contextgotocalls in your code. You're better off returning a result from theWithdrawmethod.