Замените
if (LastCoinsDeliveryInfo == numberOfCoins)
loop = false;
coinsCount = numberOfCoins - LastCoinsDeliveryInfo;
на
if (LastCoinsDeliveryInfo == coinsCount)
loop = false;
coinsCount -= LastCoinsDeliveryInfo;
Ибо я подозреваю, что
LastCoinsDeliveryInfo
содержит лишь число монет, выданных в последний раз.
Но вообще, так асинхронный код не пишется. Thread.Sleep - это детский сад какой-то. Используйте лучше Future/Promise, или wait/notify, что там в C# есть. Помимо неэффективности, асинхронное изменение полей
SendDispenseCoins
и
SendDispenseAllCoins
может и не сработать: основной поток может просто не увидеть изменения, сделанные другим потоком.