WCF вложенный обратный вызов - PullRequest
0 голосов
/ 13 июня 2009

Фон: я пытаюсь переслать серверное событие ApplyChangeFailed , которое запускается службами синхронизации для ADO 1.0 DBServerSyncProvider, клиенту. Все примеры кода для разрешения конфликтов служб Sync не используют WCF, и когда клиент подключается к базе данных сервера напрямую, этой проблемы не существует. Однако мой DBServerSyncProvider упакован безголовой службой WCF, и я не могу показать пользователю диалог с ошибочными данными для просмотра.

Таким образом, очевидным решением, по-видимому, является преобразование службы HTTP WCF, созданной службами синхронизации, в TCP, создание дуплексного соединения и определение обработчика обратного вызова на клиенте, который получает объект SyncConflict , и устанавливает свойство Action события.

Когда я это сделал, я получил ошибку во время выполнения (до попытки обратного вызова):

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

Итак, я сделал то, что предлагалось в сообщении, и украсил и сервис, и поведение обратного вызова атрибутом Multiple. Тогда ошибка выполнения исчезла, но вызов приводит к «тупику» и никогда не возвращается. Что мне делать, чтобы обойти это? Разве невозможно иметь службу WCF, которая перезванивает клиенту до возврата исходного вызова службы?

Редактировать: Я думаю, это могло бы быть объяснением проблемы, но я все еще не уверен, каким должно быть правильное решение.

Ответы [ 2 ]

1 голос
/ 15 июня 2009

После обновления ConcurrencyMode вы пытались запустить обратный вызов в отдельном потоке?

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

0 голосов
/ 15 июня 2009

При запуске агента синхронизации в отдельном потоке на клиенте обратный вызов работает просто отлично:

    private int kickOffSyncInSeparateThread()
    {
        SyncRunner syncRunner = new SyncRunner();
        Thread syncThread = new Thread(
               new ThreadStart(syncRunner.RunSyncInThread));

        try
        {
            syncThread.Start();
        }
        catch (ThreadStateException ex)
        {
            Console.WriteLine(ex);
            return 1;
        }
        catch (ThreadInterruptedException ex)
        {
            Console.WriteLine(ex);
            return 2;
        }
        return 0;
    }

А это мой SyncRunner:

class SyncRunner
{
    public void RunSyncInThread()
    {
        MysyncAgent = new MySyncAgent();

        syncAgent.addUserIdParameter("56623239-d855-de11-8e97-0016cfe25fa3");
        Microsoft.Synchronization.Data.SyncStatistics syncStats = 
              syncAgent.Synchronize();
    }
}
...