Вложенный обратный вызов WCF

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

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

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

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

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

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


person cdonner    schedule 13.06.2009    source источник


Ответы (2)


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

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

person mundeep    schedule 15.06.2009
comment
Подумав еще немного, я понял, что в теме за ссылкой в ​​моем посте есть отличное обоснование этой проблемы. Проблема не в том, что обратный вызов нужно делать в отдельном потоке. Поскольку он работает на сервере, это не имеет значения. Взаимная блокировка происходит на клиенте. Я отправлю ответ с моим кодом. - person cdonner; 15.06.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();
    }
}
person cdonner    schedule 15.06.2009