2012-02-06 3 views
3

В настоящее время я просматриваю код, который в основном считывает данные по строке из файла и вызывает соответствующий метод для клиента WCF для каждой строки. Моя проблема с кодом является то, что новый клиент создается для каждой операции, а именно:Вызов нескольких операций с клиентом WCF

function CallSomeOp(line) 
{ 
    using (var client = new Client() 
    { 
     client.SomeOp(line); 
    } 
} 

Это кажется, что клиент будет закрыть соединение и открыть новый для каждой строки в файле, который, кажется, как большой накладные расходы , То, что я хотел бы сделать, это переместить создание клиента вне функции и в инициализации, так что несколько операций называются на одного клиента, то есть:

using (var client = new Client()) 
{ 
    for(var line in lines) 
    { 
     CallSomeOp(line, client); 
    } 
} 

Но я не уверен, если это нормально или не. Есть ли какая-то проблема с вызовом нескольких операций на клиенте, то есть в конечном итоге у меня закончится память или что-то еще?

ответ

2

Операция, как правило, без гражданства, так что это ожидаемое поведение. Вы можете изменить InstanceContextMode. Это определяет, создается ли новый экземпляр с каждым вызовом или существует один экземпляр. Вопрос в том, должен ли ты? Как я уже сказал, один вызов обычно без гражданства. Только один экземпляр не очень хорошо масштабируется. Я бы предложил оставить InstanceContextMode PerCall. Таким образом, для каждого вызова веб-сервер создает один экземпляр, я бы не стал слишком беспокоиться о накладных расходах. Если накладные расходы действительно становятся проблемой, возможно, служба не то, что вам нужно.

Тогда есть ConcurrencyMode, который позволяет указать несколько потоков, которые нужно создать.

Что касается клиента, вам не нужно его повторно создавать каждый раз, когда вы хотите вызвать операцию. В качестве альтернативы вы также можете посмотреть на ChannelFactory, если оба клиента и сервер знают о контракте. This answer содержит некоторые детали.

+0

Спасибо за ответ, я сделал эксперимент с профилировщиком и с помощью одного экземпляра сократил время работы с 58 секунд до 25. Я не знаю, что много о WCF, но это похоже на быструю победу. – avid

+0

Можете ли вы опубликовать код вашего сервиса? Что оно делает? Помните о том, что один экземпляр может привести к проблемам масштабирования со многими вызовами. – diggingforfire

+0

Я не могу опубликовать код сервиса, и я не совсем уверен, что он делает! Он должен просто взять некоторые данные и поместить их где-нибудь. Заявитель, использующий клиент, является однопоточным. – avid

2

Это, безусловно, хорошая идея, чтобы повторно использовать клиент WCF через несколько вызовов, поскольку действительно существует стоимость в создании новых экземпляров этого, даже если that's been improved in later versions.

Самое главное, чтобы быть в курсе при повторном использовании клиента WCF, однако, является то, что если операция служба не, весь клиент будет поставлен в faulted state и не может больше использоваться.

Вам нужно будет принять это во внимание в своем клиентском коде. В зависимости от ваших требований, один из способов справиться с этой ситуацией может быть воссоздавать клиент прокси в случае сбоя и продолжить обработку ввода, как показано в следующем примере:

var client = new ServiceClient(); 

foreach (var line in lines) 
{ 
    try 
    { 
     client.DoSomething(line); 
    } 
    catch 
    { 
     client.Abort(); 
     client = new ServiceClient() 
    } 
} 

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

+0

Спасибо за это, это хорошо знать. – avid

Смежные вопросы