2016-01-31 5 views
1

Я пытаюсь использовать порты завершения ввода-вывода, используя обратный вызов WCF в дуплексном контракте. Я использую следующую простую линию, чтобы сделать это:C# Как выполнить ввод/вывод Asynchrounus с использованием портов завершения с шаблонами APM-TAP на обратном вызове WCF?

OperationContext.Current.OnPushData(data); 

Где OnPushData является операцией по контракту обратного вызова, который выполняется на стороне клиента.
С этой линии, представляющий ответ (операция вывода) с использованием какой-то сетевой интерфейс и WCF также опираясь на ThreadPool потоков, которые могут быть использованы в качестве рабочих потоков или ввода/вывода CompletionPortThread, это будет хорошей идеей используйте записи ввода-вывода CompletionPortThreads, записав в порт завершения, используя TAP или APM Шаблоны (Как упоминается в статье, о которой я упоминал) вместо использования обычного рабочего потока, который значительно увеличит производительность.

+2

Я не уверен, что вы используете подходящий инструмент для работы. IIUC, вы программируете (читаете: сворачиваете самостоятельно) паб/суб-сервер. Возможно, существующие реализации дадут вам хорошее решение за меньшее время. Взгляните на SignalR (http://signalr.net/), Redis (http://redis.io/topics/pubsub) и т. Д. –

+0

'Parallel.ForEach' вряд ли будет использовать потоки IO по вашему желанию, http://blogs.msdn.com/b/ericeil/archive/2008/06/20/windows-io-threads-vs-managed-io-threads.aspx, так как вместо этого он должен обернуть рабочие потоки. Вы используете WCF таким образом, чтобы его оригинальный дизайн. Каждый вызов WCF должен быть небольшим и быстрым с разумным таймаутом. Как и в других комментариях, для непредсказуемого тайм-аута или долгого выполнения задач SignalR - это лучшее решение для поиска. –

+0

Само время обработки не так много. На самом деле это всего лишь несколько миллисекунд (~ 10), и он работает по отдельному потоку отдельно от WCF. Я не могу переключиться на SignalR прямо сейчас, потому что WCF является стандартом для нашей компании, и все приложение уже построено поверх WCF. Я использую parallel.for каждый только для вызова метода обратного вызова клиента, который в значительной степени определяется как Дуплексный контракт для WCF. –

ответ

0

Короткий ответ:
Хитрость, чтобы иметь возможность использовать Асинхронный I/O с дуплексной WCF контракта является следующий простой код:

[OperationContract(IsOneWay = true)] 
    Task OnPushData(data); 

Просто вам необходимо изменить тип возвращаемого обратного вызова контрактный метод должен быть Задача. но этого недостаточно, необходимо реализовать метод асинхронной так:

public async Task PublishData() 
    { 
     communicationCallback = (ICommunicationObject)service.Callback; 
     if (communicationCallback.State == CommunicationState.Opened) 
     { 
       await service.Callback.OnPushData(data); 
     } 
    } 

Это все. Это фактически повышает производительность моего приложения. и теперь я могу видеть завершение I/O Ports темы, используемые вызова ThreadPool.GetAvailableThreads (рабочих, IO)

Некоторые Explinations:
Как я понимаю, чтобы иметь возможность использовать механизм асинхронного ввода/вывода , вам необходимо будет сделать следующее:

1- Определение операции ввода-вывода.
2- Метод, который будет инкапсулировать вашу логику асинхронного ввода-вывода.
3- Механизм обратного вызова, который будет вызываться, когда асинхронный ввод-вывод завершен, и его целью в основном является получение результата ввода-вывода Async.
4- Объект, который будет содержать результат ввода-вывода Async.

.NET Framework обеспечивает 3 шаблонов проектирования, чтобы сделать это:

1- IAsyncResult Asynchrnous Узор: где BeginXXX и EndXXX будет инкапсулировать асинхронной логики наряду с обратный вызов делегата, что представляет метод обратного вызова и, конечно, объект IAsyncResult, используемый для хранения вашего результата асинхронного ввода-вывода.
2- Асинхронный шаблон на основе задач: Использование только одного класса, который равен Задача вместе с ключевыми словами async/await, которые облегчают использование шаблона TAP.
3- Асинхронный шаблон на основе событий.

Вы можете узнать больше о том, как вы можете использовать эти шаблоны служб WCF на How to Implement an Asynchronous Service Operation

Однако, предыдущая ссылка отлично подходит для реализации запроса асинхронного/услуги ответа, хотя, нет никаких объяснений о том, как сделать поэтому с контрактом обратного вызова.
К сожалению, в моем случае я должен реализовать подписчик/издатель patttern с использованием среды WCF, где периодическая публикация данных периодически запускается службой (каждые 1 секунду).

Подробнее:
Я постараюсь сделать это как можно короче:
WCF полагается на ThreadPool предоставляемой .NET Framework. ThreadPool имеет 2 вида потоков:
1- Рабочие темы: для вычислений.
2- Порт ввода-вывода ввода-вывода Нити: Используется для получения результата операции ввода-вывода.

Вы должны различать тему IOCP Thread и IOCP Object, инициированную CLR. Роль IOCP Thread заключается в том, чтобы доставить результат операции ввода-вывода, в то время как объект IOCP - это объект, инициированный CLR, чтобы получить все запросы ввода-вывода. Другими словами, они сотрудничают для достижения операции ввода-вывода.

Первое, что вам нужно знать, что любой запрос ввода/вывода вы сделали приведет к системному вызову, который будет инициировать объект Called IRP (I/O запрос Packet) используется ли синхронная или асинхронная парадигма.

ввода/вывода Завершение Порт (IOCP) не что иное, как очереди, как объект, инициированной CLR. Этот объект несет ответственность за получение всех Выполненные запросы ввода-вывода (IRPs). На данный момент здесь есть две возможности:
1- Операция ввода-вывода вызывается синхронным способом: в этом случае поток вызывающего абонента будет заблокирован до завершения операции ввода-вывода.
2- Операция ввода-вывода вызывается методом асинхронизации: в этом случае поток вызывающего абонента продолжит выполнение, и он не будет заблокирован для операции ввода-вывода до завершения.

Предположив, что вы используете метод асинхронного, Когда асинхронная операция ввода/вывод завершена, это означает, что IRP объекта обрабатывается, и теперь он будет поставлен в очередь на IOCP объекта. ThreadPool IOCP нити придет играть роль потянув относительную IRP из IOCP, который будет обернут в IAsyncResult ПАТ или Task объекта для TAP и передавая этот объект вашего уровня приложения через Механизм обратного вызова.

Некоторые Литература:

[1]: https://msdn.microsoft.com/en-us/library/ms734701.aspx
[2]: http://blog.stephencleary.com/2012/08/async-wcf-today-and-tomorrow.html
[3]: http://southworks.com/blog/2013/10/29/asynchronous-io-in-c-io-completion-ports/
[4]: ​​http://southworks.com/blog/2013/08/02/asynchronous-io-in-c-introduction/
[5]: http://mikehadlow.blogspot.com/2011/03/7000-concurrent-connections-with.html
[6]: https://msdn.microsoft.com/en-us/library/ms731177(v=vs.110).aspx
[7]: http://www.amazon.es/Clr-Via-C-Developer-Reference/dp/0735667454