0

背景:我正在尝试将由 ADO 1.0 DBServerSyncProvider 的同步服务触发的服务器端ApplyChangeFailed事件转发给客户端。Sync Services冲突解决的所有代码示例都没有使用WCF,当客户端直接连接到服务器数据库时,不存在这个问题。但是,我的 DBServerSyncProvider 由无头 WCF 服务包装,并且我无法向用户显示包含有问题数据的对话框以供查看。

因此,显而易见的解决方案似乎是将 Sync Services 生成的 HTTP WCF 服务转换为 TCP,使其成为双工连接,并在接收SyncConflict对象并设置事件的 Action 属性的客户端上定义一个回调处理程序。

当我这样做时,我得到了一个运行时错误(在尝试回调之前):

System.InvalidOperationException:此操作将死锁,因为在当前消息完成处理之前无法接收到回复。如果要允许无序消息处理,请在 CallbackBehaviorAttribute 上指定 Reentrant 或 Multiple 的 ConcurrencyMode。

所以我按照消息的建议做了,并用 Multiple 属性修饰了服务和回调行为。然后运行时错误消失了,但调用导致“死锁”并且永远不会返回。我该怎么做才能解决这个问题?在原始服务调用返回之前,是否不可能有一个回调客户端的 WCF 服务?

编辑:我认为可能是对问题的解释,但我仍然不确定正确的解决方案应该是什么。

4

2 回答 2

1

更新 ConcurrencyMode 后,您是否尝试过在单独的线程中触发回调?

This answer to another question有一些示例代码可以启动另一个线程并通过回调,您也许可以根据您的目的修改该设计?

于 2009-06-15T08:26:31.110 回答
0

通过在客户端的单独线程中启动同步代理,回调可以正常工作:

    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();
    }
}
于 2009-06-15T14:11:33.183 回答