Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步双工WCF+;流程管理器_C#_Wcf_Asynchronous_Duplex_Saga - Fatal编程技术网

C# 异步双工WCF+;流程管理器

C# 异步双工WCF+;流程管理器,c#,wcf,asynchronous,duplex,saga,C#,Wcf,Asynchronous,Duplex,Saga,我正在寻找一种方法,让客户端调用从客户端UI到WCF服务主机的异步进程,然后通知客户端进程的状态。我想这可以通过sagas(进程管理器)、域事件和WCF双工连接来实现,但我不确定如何实现 案例顺序(我猜)如下: 客户端调用进程 客户端创建WCF代理 代理连接到服务主机 服务主机创建到客户端的双工通道 服务主机使用命令总线启动进程并通过双工通道 进程状态更改 定位相关双工信道 推回状态更改 客户端接收状态更改并可视化 我说的对吗?简而言之,相关的类是什么样子的?是的,我知道NServiceBus(

我正在寻找一种方法,让客户端调用从客户端UI到WCF服务主机的异步进程,然后通知客户端进程的状态。我想这可以通过sagas(进程管理器)、域事件和WCF双工连接来实现,但我不确定如何实现

案例顺序(我猜)如下:

  • 客户端调用进程
  • 客户端创建WCF代理
  • 代理连接到服务主机
  • 服务主机创建到客户端的双工通道
  • 服务主机使用命令总线启动进程并通过双工通道
  • 进程状态更改
  • 定位相关双工信道
  • 推回状态更改
  • 客户端接收状态更改并可视化
  • 我说的对吗?简而言之,相关的类是什么样子的?是的,我知道NServiceBus(在这种情况下经常提到它),但我不想依赖其他框架(我已经有了很多NServiceBus可以自己解决的问题,我已经使用了数百种不同的框架来处理各种各样的问题……)

    编辑:示例 下面是一个现实世界的例子,可能会详细说明我的问题

    我有一个图像处理服务器,它可以用图像做一些魔术和独角兽的东西。周转基金
    客户端将图像上载到服务器,然后显示一个进度条,指示图像已处理了多少。服务器启动一个新的ImageProcessService(在请求范围内)。在处理过程中,他可能抛出许多ImageProcessStateChanged事件,其中的数字表示进程的百分比。做完后,他可能会扔一个假发。所有事件都应该由事件总线捕获,事件总线将它们发回正确的客户端。该过程可能需要60秒,每个客户端可以触发一次,但要尽可能多的客户端

    这可以通过使用任务并行或IAsyncResult来实现

    IAsyncResult的AsyncWaitHandle上有一个WaitOne,因此客户端可以等待它完成异步执行,然后通过调用异步方法的End调用来获取值

    例如

    public IAsyncResult Process(type param, AsyncCallback callback, object state)
    {
       // code here to process
    }
    
    public TypeResult EndProcess(IAsyncResult ar)
    {
       // return result here
    }
    
    现在可以使用回调从客户机调用方法,在您的情况下,可以使用回调通知状态


    有关IAsyncResult的详细信息:

    这可以使用任务并行或IAsyncResult实现

    IAsyncResult的AsyncWaitHandle上有一个WaitOne,因此客户端可以等待它完成异步执行,然后通过调用异步方法的End调用来获取值

    例如

    public IAsyncResult Process(type param, AsyncCallback callback, object state)
    {
       // code here to process
    }
    
    public TypeResult EndProcess(IAsyncResult ar)
    {
       // return result here
    }
    
    现在可以使用回调从客户机调用方法,在您的情况下,可以使用回调通知状态


    有关IAsyncResult的详细信息:

    听起来您所要寻找的似乎是通过在操作合同上设置IsOneWay=true来启用的行为。当您在操作契约中设置IsOneWay=true时,调用方发送请求但不等待响应。 要获得响应,被调用方需要在双工通道的回调通道上调用另一个操作,该通道也设置了IsOneWay=true

    下面是一个简单的例子:

    服务合同:

    [ServiceContract( CallbackContract = typeof( IClientCallback ), SessionMode = SessionMode.Required )]
    public interface IClientService
    {
        [OperationContract( IsInitiating = true )]
        void CreateSession( string windowsUserName );
        [OperationContract( IsOneWay = true )]
        void LongOp( );
        [OperationContract( IsTerminating = true )]
        void Terminate( );
    }
    
    [ServiceContract]
    public interface IClientCallback
    {
        [OperationContract( IsOneWay = true )]
        void LongOpResponse( );
    }
    
    客户端回调合同:

    [ServiceContract( CallbackContract = typeof( IClientCallback ), SessionMode = SessionMode.Required )]
    public interface IClientService
    {
        [OperationContract( IsInitiating = true )]
        void CreateSession( string windowsUserName );
        [OperationContract( IsOneWay = true )]
        void LongOp( );
        [OperationContract( IsTerminating = true )]
        void Terminate( );
    }
    
    [ServiceContract]
    public interface IClientCallback
    {
        [OperationContract( IsOneWay = true )]
        void LongOpResponse( );
    }
    
    服务实施:

    class ServerService : IClientService
    {
        public void CreateSession( string windowsUserName )
        {
            //Do stuff to set up your session as desired
        }
    
        public void LongOp( )
        {
            //Do something that takes a long time
            LongRunningFunctionCall();
            Callback.LongOpResponse();
        }
    
        public void Terminate( )
        {
            //Do stuff to tear down your session
        }
    
        public IClientCallback Callback { get { return OperationContext.Current.GetCallbackChannel<IClientCallback>( ); } }
    }
    
    只要您有一个对处理每个会话的客户机服务对象的引用,就可以直接通过该对象访问其回调通道,这样,只要通道打开,就可以从服务器应用程序中的任何点启动回调协定上的函数


    在双工信道的服务合同中,我们通常会得到比IsOneWay=false更多的单向操作,除了即时响应对于继续调用应用程序至关重要的操作之外。

    听起来您所要寻找的是通过在操作契约上设置IsOneWay=true来启用的行为。当您在操作契约中设置IsOneWay=true时,调用方发送请求但不等待响应。 要获得响应,被调用方需要在双工通道的回调通道上调用另一个操作,该通道也设置了IsOneWay=true

    下面是一个简单的例子:

    服务合同:

    [ServiceContract( CallbackContract = typeof( IClientCallback ), SessionMode = SessionMode.Required )]
    public interface IClientService
    {
        [OperationContract( IsInitiating = true )]
        void CreateSession( string windowsUserName );
        [OperationContract( IsOneWay = true )]
        void LongOp( );
        [OperationContract( IsTerminating = true )]
        void Terminate( );
    }
    
    [ServiceContract]
    public interface IClientCallback
    {
        [OperationContract( IsOneWay = true )]
        void LongOpResponse( );
    }
    
    客户端回调合同:

    [ServiceContract( CallbackContract = typeof( IClientCallback ), SessionMode = SessionMode.Required )]
    public interface IClientService
    {
        [OperationContract( IsInitiating = true )]
        void CreateSession( string windowsUserName );
        [OperationContract( IsOneWay = true )]
        void LongOp( );
        [OperationContract( IsTerminating = true )]
        void Terminate( );
    }
    
    [ServiceContract]
    public interface IClientCallback
    {
        [OperationContract( IsOneWay = true )]
        void LongOpResponse( );
    }
    
    服务实施:

    class ServerService : IClientService
    {
        public void CreateSession( string windowsUserName )
        {
            //Do stuff to set up your session as desired
        }
    
        public void LongOp( )
        {
            //Do something that takes a long time
            LongRunningFunctionCall();
            Callback.LongOpResponse();
        }
    
        public void Terminate( )
        {
            //Do stuff to tear down your session
        }
    
        public IClientCallback Callback { get { return OperationContext.Current.GetCallbackChannel<IClientCallback>( ); } }
    }
    
    只要您有一个对处理每个会话的客户机服务对象的引用,就可以直接通过该对象访问其回调通道,这样,只要通道打开,就可以从服务器应用程序中的任何点启动回调协定上的函数


    在我们的双工信道服务合同中,除了即时响应对呼叫应用程序的继续至关重要的操作外,通常比IsOneWay=false的操作更多的是单向操作。

    您的操作在双工信道上可以执行多少次server@K.B什么?需要多长时间?大约30秒。难道你不能设置一个长的超时时间并就进度向客户撒谎吗?@Zache我上面的例子很好。。只是一个例子。您的解决方案可能适用于此,但是我的客户机需要在此过程中发生的状态更改(这是关于网络发现功能)。所以不,我不能伪造并等待超时。您希望使用哪种类型的UI(winform、WPF、Asp.Net、Silverlight)和协议(wsDualHttpBinding、NetCpBinding和netNamedPipeBinding),因为对于每种不同的体系结构,您的操作需要多少时间server@K.B什么?需要多长时间?大约30秒。难道你不能设置一个长的超时时间并就进度向客户撒谎吗?@Zache我上面的例子很好。。只是一个例子。您的解决方案可能适用于此,但是我的客户机需要在此过程中发生的状态更改(这是关于网络发现功能)。所以不,我不能假装