Нужно ли закрывать соединение со службой 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.
- В идеале, когда клиент вызывает односторонний метод, он должен быть заблокирован только на самый короткий момент, необходимый для отправки вызова. Однако в действительности односторонние вызовы не приравниваются к асинхронным вызовам. Когда односторонние вызовы достигают службы, они могут отправляться не сразу, а вместо этого могут буферизироваться на стороне службы для отправки по одному, в соответствии с настроенным режимом параллелизма службы
- Хотя односторонние операции не возвращают значения или исключения из самой службы, неправильно воспринимать их как улицу с односторонним движением или "черную дыру", из которой ничего не может выйти. Клиент по-прежнему должен ожидать исключения из одностороннего вызова и может даже сделать вывод, что вызов не выполнен в службе. При отправке односторонней операции любая ошибка из-за проблем со связью (таких как неправильный адрес или недоступность хоста) вызовет исключение на стороне клиента, пытающегося вызвать операцию.
Если я удалю client.Close(), консольное приложение будет работать так, как я хочу, но я не уверен, что канал останется открытым, даже если консольное приложение больше не работает?
Односторонний вызов по своей природе не является "забытым", поскольку клиент может обнаружить, что во время одностороннего вызова что-то пошло не так в службе.
Здесь вы пытаетесь вызывать одностороннюю операцию асинхронно и, следовательно, вы не можете закрыть соединение или прокси.
[OperationContract(IsOneWay = true,AsyncPattern = true)]
IAsyncResult ExecuteCleanup(AsyncCallback callback,object asyncState);
client.ExecuteCleanup(,null,null);
Примечание. Если вы не хотите усложнять ситуацию, убедитесь, что ExecuteCleanup является последним вызовом в вашей службе, а затем вы можете закрыть его, что не повлияет на последующие операции. Возможная реализация Как правильно закрыть клиентский прокси (существующее соединение было принудительно закрыто удаленным хостом)?