Нужно ли закрывать соединение со службой WCF с консоли, которая выходит сразу?

У меня есть консольное приложение, которое я хочу сделать вызовом "уволить и забыть" для службы WCF, а затем закрыть его, не дожидаясь ответа. Это только должно инициировать работу по очистке. Работа может занять несколько часов, поэтому я не хочу, чтобы консольное приложение оставалось открытым и ждали его.

Я добавил "IsOneWay=true" в методы контракта, но консольное приложение все еще ожидает завершения задачи, прежде чем выполнить client.close() и завершить работу.

Если я удалю client.Close(), консольное приложение будет работать так, как я хочу, но я не уверен, что канал останется открытым, даже если консольное приложение больше не работает?

Вот мой код консольного приложения:

static void Main(string[] args)
{
    Console.WriteLine("Starting Cleanup");

    var client = new IntegrationWcfServiceClient(EndPointConfigurationName);

    try
    {
        client.ExecuteCleanup();
        //client.Close();
    }
    catch (Exception ex)
    {
        client.Abort();
        WriteLineRed($"Couldn't start cleanup: {ex.Message}");
        return;
    }

    WriteLineGreen("Cleanup started successfully");
}

А вот код договора об операции:

[OperationContract(IsOneWay = true)]
void ExecuteCleanup();

1 ответ

Есть несколько вещей, которые вы должны учитывать при совершении одностороннего вызова. Из книги программирование сервисов WCF.

  1. В идеале, когда клиент вызывает односторонний метод, он должен быть заблокирован только на самый короткий момент, необходимый для отправки вызова. Однако в действительности односторонние вызовы не приравниваются к асинхронным вызовам. Когда односторонние вызовы достигают службы, они могут отправляться не сразу, а вместо этого могут буферизироваться на стороне службы для отправки по одному, в соответствии с настроенным режимом параллелизма службы
  2. Хотя односторонние операции не возвращают значения или исключения из самой службы, неправильно воспринимать их как улицу с односторонним движением или "черную дыру", из которой ничего не может выйти. Клиент по-прежнему должен ожидать исключения из одностороннего вызова и может даже сделать вывод, что вызов не выполнен в службе. При отправке односторонней операции любая ошибка из-за проблем со связью (таких как неправильный адрес или недоступность хоста) вызовет исключение на стороне клиента, пытающегося вызвать операцию.

Если я удалю client.Close(), консольное приложение будет работать так, как я хочу, но я не уверен, что канал останется открытым, даже если консольное приложение больше не работает?

Односторонний вызов по своей природе не является "забытым", поскольку клиент может обнаружить, что во время одностороннего вызова что-то пошло не так в службе.

Здесь вы пытаетесь вызывать одностороннюю операцию асинхронно и, следовательно, вы не можете закрыть соединение или прокси.

[OperationContract(IsOneWay = true,AsyncPattern = true)]
IAsyncResult ExecuteCleanup(AsyncCallback callback,object asyncState);

client.ExecuteCleanup(,null,null);

Примечание. Если вы не хотите усложнять ситуацию, убедитесь, что ExecuteCleanup является последним вызовом в вашей службе, а затем вы можете закрыть его, что не повлияет на последующие операции. Возможная реализация Как правильно закрыть клиентский прокси (существующее соединение было принудительно закрыто удаленным хостом)?

Другие вопросы по тегам