Нечетная проблема WCF - PullRequest
       5

Нечетная проблема WCF

1 голос
/ 20 сентября 2009

У меня есть сервер-клиент, использующий WCF.

На сервере есть список клиентов.

Чтобы проверить время ожидания, каждую минуту он отправляет бит данных (ping) каждому клиенту. Вся отправка выполняется асинхронно - поэтому строка выглядит так:

for (int i = 0; i < MaxUsers; i++)
{
    if (_clients[i] != null)
    {
        _clients[i].Client.BeginSendToClient("PING", new AsyncCallback(this.SendToClientCallback), _clients[i].Client);

Теперь метод SentToClientCallback запускается так:

void SendToClientCallback(IAsyncResult asyncResult)
{
    IClientAsync callback = null;
    try
    {
        callback = (IClientAsync)asyncResult.AsyncState;
        callback.EndSendToClient(asyncResult);
    }
    catch (TimeoutException e)

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

int myClientIndex = GetClientIndexFromCallback(CurrentCallback);

, где

private int GetClientIndexFromCallback(IClientAsync callback)
{

    for (int i = 0; i < MaxUsers; i++)
    {
        if (_clients[i] != null && _clients[i].Client.Equals(callback))
        {
            // found
            return i;

Теперь этот код работает нормально, если я подключаюсь, затем отключаюсь. Он отправляет PING, переходит к методу обратного вызова. Это генерирует исключение тайм-аута. Он получает идентификационный номер (который равен 0) и удаляет _client [0], и все хорошо.

Однако, если я подключаюсь и отключаюсь дважды подряд, до того, как истечет время ожидания первого подключения, отключится только одно из подключений (второе или _client [1]). Другой остается, и постоянно отправляется PING. Метод обратного вызова продолжает работать и генерирует исключение тайм-аута ... но когда я вызываю свой метод, чтобы получить его идентификатор, он не может его найти. По какой-то причине _clients[i].Client.Equals(callback) не возвращает истину.

Как это возможно? Каждая команда PING отправляет _clients[0].Client, но когда я сравниваю ее в своем методе, она возвращает false.

Ответы [ 3 ]

0 голосов
/ 20 сентября 2009

Просто любопытно, но почему вы начинаете с индекса в массиве, отправляете в прокси-объект WCF, а затем снова начинаете искать его индекс в массиве. Кажется, намного проще и безопаснее отправлять в индекс, когда AsyncState и ваши проблемы исчезли.

0 голосов
/ 20 сентября 2009

Как реализован метод Equals для IClientAsync?

Также я согласен с Slashene, что это может быть связано с темами. Асинхронные обратные вызовы будут поступать в разные потоки. Каждый из них работает с одним и тем же массивом, один из потоков может «удалять» элемент из массива, в то время как другой находится на полпути через его итерацию.

Откуда берется значение для MaxUsers? это общее количество подключенных пользователей?

0 голосов
/ 20 сентября 2009

кажется, что вы получаете доступ к _clients из нескольких потоков. Список не является потокобезопасным. Это объяснило бы это странное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...