Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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_Client Server - Fatal编程技术网

C# 在WCF中实现客户端回调功能

C# 在WCF中实现客户端回调功能,c#,wcf,client-server,C#,Wcf,Client Server,我正在处理的项目是一个客户机-服务器应用程序,所有服务都用WCF编写,客户机用WPF编写。有些情况下,服务器需要将信息推送到客户端。我最初考虑使用WCF双工服务,但在网上做了一些研究之后,我发现很多人出于很多原因都在避免使用它 我考虑的下一件事是让客户机创建一个主机连接,以便服务器可以使用该连接对客户机进行服务调用。然而,问题是应用程序是通过internet部署的,因此该方法需要配置防火墙以允许传入流量,并且由于大多数用户是普通用户,因此可能还需要配置路由器以允许端口转发,这对用户来说也是一件麻

我正在处理的项目是一个客户机-服务器应用程序,所有服务都用WCF编写,客户机用WPF编写。有些情况下,服务器需要将信息推送到客户端。我最初考虑使用WCF双工服务,但在网上做了一些研究之后,我发现很多人出于很多原因都在避免使用它

我考虑的下一件事是让客户机创建一个主机连接,以便服务器可以使用该连接对客户机进行服务调用。然而,问题是应用程序是通过internet部署的,因此该方法需要配置防火墙以允许传入流量,并且由于大多数用户是普通用户,因此可能还需要配置路由器以允许端口转发,这对用户来说也是一件麻烦事

我的第三个选项是,在客户端中,生成一个后台线程,该线程调用服务器上的
GetNotifications()
方法。然后,服务器端的这个方法会阻塞,直到创建了实际的通知,然后通知线程(使用
AutoResetEvent
object-maybe?),并将信息发送到客户端。这个想法是这样的:

客户端

private void InitializeListener()
{
    Task.Factory.StartNew(() =>
    {
        while (true)
        {
            var notification = server.GetNotifications();

            // Display the notification.
        }
    }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
服务器

public NotificationObject GetNotifications()
{
    while (true)
    {
         notificationEvent.WaitOne();
         return someNotificationObject;
    }
}

private void NotificationCreated()
{
    // Inform the client of this event.
    notificationEvent.Set();
}
在这种情况下,
NotificationCreated()
是一种回调方法,当服务器需要向客户端发送信息时调用


你认为这种方法怎么样?这是可伸缩的吗?

对于要在服务器上保留线程的每个客户端。如果您有几百个客户机,而服务器无论如何都不会使用内存,那就可以了。如果可以有更多的客户端,或者您不希望每个客户端刻录1MB的堆栈,则应进行一些更改:

  • 使用异步WCF操作方法。它们允许您在方法等待时取消阻止请求线程
  • 将事件模型更改为异步一次
    SemaphoreSlim
    具有异步支持。您还可以使用
    TaskCompletionSource

  • 这样,您可以扩展到多个连接。

    对于每个客户端,您将在服务器上保留一个线程。如果您有几百个客户机,而服务器无论如何都不会使用内存,那就可以了。如果可以有更多的客户端,或者您不希望每个客户端刻录1MB的堆栈,则应进行一些更改:

  • 使用异步WCF操作方法。它们允许您在方法等待时取消阻止请求线程
  • 将事件模型更改为异步一次
    SemaphoreSlim
    具有异步支持。您还可以使用
    TaskCompletionSource

  • 这样,您可以扩展到多个连接。

    谢谢您的回答。客户端正在使用.NET 4.0,因此此时无法支持
    async
    。你能详细说明一下第二个问题吗?不确定您所说的
    将事件模型更改为异步一次是什么意思。
    .1:客户端和服务器通过二进制网络协议100%分离。一个可以使用异步,另一个可以做任何它想做的事情,包括在用C编程的手表上运行或不使用异步。清楚吗?;2:如果你在服务器上阻止了一个事件,那么你就阻塞了一个线程(这意味着什么,请参阅我的答案)。所以你不想等待事件发生
    SemaphoreSlim.WaitOneAsync
    允许您在不阻塞线程的情况下进行逻辑等待。研究一下它是如何工作的,以及它是如何与WCF异步操作一起工作的。我们将对此进行研究。谢谢你,伙计,谢谢你的回答。客户端正在使用.NET 4.0,因此此时无法支持
    async
    。你能详细说明一下第二个问题吗?不确定您所说的
    将事件模型更改为异步一次是什么意思。
    .1:客户端和服务器通过二进制网络协议100%分离。一个可以使用异步,另一个可以做任何它想做的事情,包括在用C编程的手表上运行或不使用异步。清楚吗?;2:如果你在服务器上阻止了一个事件,那么你就阻塞了一个线程(这意味着什么,请参阅我的答案)。所以你不想等待事件发生
    SemaphoreSlim.WaitOneAsync
    允许您在不阻塞线程的情况下进行逻辑等待。研究一下它是如何工作的,以及它是如何与WCF异步操作一起工作的。我们将对此进行研究。谢谢你,伙计。