Вы смешиваете фактическую реализацию службы (реализацию интерфейса IBank) и хост-службу в одном и том же классе.
Это определенно НЕ хорошая практика.
По умолчанию WCF намеренно создает новую отдельную копию класса реализации вашего сервиса для каждого входящего запроса. Это значительно облегчает написание сервиса (не нужно суетиться с многопоточностью - каждый запрос получает свой собственный класс) .
НО : вам не следует смешивать это с ServiceHost, поскольку вам действительно нужен только один экземпляр узла службы для размещения класса службы, который может обрабатывать сотни или тысячи запросов.
Итак - создайте один класс
class BankImplementation : IBank
{
private static int _instanceCounter;
BankOperationResult IBank.Put(int amount)
{
Console.WriteLine(string.Format("{0:00} {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread) + " Putting...");
//WCFConsoleHostApp.amount += amount;
Thread.Sleep(20000);
Console.WriteLine(string.Format("{0:00} {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread) + " Putting done");
return new BankOperationResult { CurrentAmount = WCFConsoleHostApp.amount, Success = true };
}
BankOperationResult IBank.Withdraw(int amount)
{
Console.WriteLine(string.Format("{0:00} {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread) + " Withdrawing...");
//WCFConsoleHostApp.amount -= amount;
Thread.Sleep(20000);
Console.WriteLine(string.Format("{0:00} {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread) + " Withdrawing done");
return new BankOperationResult { CurrentAmount = WCFConsoleHostApp.amount, Success = true };
}
}
для вашего сервисного кода, а затем отдельный (возможно, даже в отдельном проекте все вместе) для размещения вашего сервисного кода:
class WCFConsoleHostApp
{
public WCFConsoleHostApp ()
{
Interlocked.Increment(ref _instanceCounter);
Console.WriteLine(string.Format("{0:T} Instance nr " + _instanceCounter + " created", DateTime.Now));
}
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(BankImplementation));
host.Open();
Console.WriteLine("Host is running...");
Console.ReadLine();
host.Close();
}
}
Теперь вы получаете один экземпляр вашего WCFConsoleHostApp
, который увеличит время выполнения WCF на host.Open()
и обработает запросы, создавая столько экземпляров класса BankImplementation
, сколько необходимо.
ОБНОВЛЕНИЕ: Ну, служба WCF также "удушена", например, Вы можете настроить количество одновременных вызовов и экземпляров. По умолчанию вы получаете 10 одновременных сеансов и 16 одновременных вызовов. Если ваша служба уже обрабатывает 16 одновременных вызовов и они спят в течение некоторого времени, дополнительные экземпляры службы не будут создаваться и обрабатываться.
См. Отличное сообщение в блоге Кенни Вольфа о деталях регулирования обслуживания. Вы можете настроить эти максимумы по своему усмотрению.