Я не могу точно сказать из вашего примера кода, где вы вызываете это, но в целом вы не должны никогда блокировать работу в потоке пользовательского интерфейса. Это заставит пользовательский интерфейс перестать отвечать на запросы, как вы упоминаете. Вы должны сделать эту работу в фоновом режиме. Я предполагаю, что вы запускаете этот цикл ConnectionIsActive непосредственно в потоке пользовательского интерфейса, что означает, что обновления состояния пользовательского интерфейса будут по существу заблокированы до тех пор, пока вы не вернетесь из этого метода.
Похоже, у вас правильная идея (с использованием асинхронных методов), но реализация кажется слишком сложной.
Удобно, WCF позволяет вам иметь асинхронный контракт на стороне клиента, даже если реализация сервера не использует асинхронные методы. Контракты просто должны иметь одинаковое имя контракта и быть помечены специально для асинхронного шаблона, как показано в этом примере:
[ServiceContract(Name = "Ping")]
interface IPing
{
[OperationContract(IsOneWay = false)]
void Ping(string data);
}
[ServiceContract(Name = "Ping")]
interface IPingClient
{
[OperationContract(AsyncPattern = true, IsOneWay = false)]
IAsyncResult BeginPing(string data, AsyncCallback callback, object state);
void EndPing(IAsyncResult result);
}
Теперь на стороне клиента вы можете использовать IPingClient
контракт и просто позвонить client.BeginPing(...)
. Он сразу же вернется, пока вся фактическая работа будет выполнена в фоновом режиме, при необходимости перезвонит вам после завершения.
Ваш код может выглядеть примерно так:
void SomeCodeInUIThread()
{
// ...
// Do something to the UI to indicate it is
// checking the connection...
client.BeginPing("...some data...", this.OnPingComplete, client);
}
void OnPingComplete(IAsyncResult result)
{
IPingClient client = (IPingClient)result.AsyncState;
try
{
client.EndPing(result);
// ...
}
catch (TimeoutException)
{
// handle error
}
// Operation is complete, so update the UI to indicate
// you are done. NOTE: You are on a callback thread, so
// make sure to Invoke back to the main form.
// ...
}