处理与整个应用程序的对象交互的并发性和复杂的WCF服务

时间:2011-05-17 11:33:13

标签: c# .net wcf concurrency

我很享受创建和托管WCF服务。 到目前为止,我可以创建定义服务和数据(接口)合同的服务,并定义主机和配置选项以达到它们(端点规范)。

好吧,考虑一下定义服务并使用它的代码(没有提到app.config中定义的端点,这里没有显示):

[ServiceContract]
public interface IMyService {
   [OperationContract]
   string Operation1(int param1);
   [OperationContract]
   string Operation2(int param2);
}

public class MyService : IMyService {
   public string Operation1(int param1) { ... }
   public string Operation2(int param2) { ... }
}

public class Program {
   public static void Main(stirng[] args) {
      using (ServiceHost host = new ServiceHost(typeof(MyService))) {
         host.Open();
         ...
         host.Close();
      }
   }
}

嗯,这种结构在创建可称为独立服务的东西时很好。 如果我需要我的服务来使用更大应用程序的对象,该怎么办? 例如,我需要一个基于我的程序中某个地方(托管服务)定义的某个集合的服务。该服务必须查看此集合并搜索并返回特定元素。

我所说的列表是由程序管理并由其编辑和修改的列表。

我有以下问题:

1)如何构建能够处理此列表的服务? 我知道可能的选项是使用重载的ServiceHost构造函数接受Object而不是Type服务。 所以我可以在那里通过我的清单。好吗?

[ServiceContract]
public interface IMyService {
   [OperationContract]
   string Operation1(int param1);
   [OperationContract]
   string Operation2(int param2);
}

public class MyService : IMyService {
   private List<> myinternallist;
   public MyService(List<> mylist) {
      // Constructing the service passing the list
   }
   public string Operation1(int param1) { ... }
   public string Operation2(int param2) { ... }
}

public class Program {
   public static void Main(stirng[] args) {
      List<> thelist;
      ...
      MyService S = new MyService(thelist)
      using (ServiceHost host = new ServiceHost(S)) {
         host.Open();
         ...
         host.Close();
         // Here my application creates a functions and other that manages the queue. For this reason my application will edit the list (it can be a thread or callbacks from the user interface)
      }
   }
}

这个例子应该澄清。 这是好的方式吗?我做对了吗?

2)如何在我的服务和我的应用程序之间处理此共享资源上的冲突? 当我的应用程序运行,托管服务时,我的应用程序可以在列表中插入项目并删除它们,同样可以执行服务。我需要互斥锁吗?怎么处理这个? 请注意,并发问题涉及两个参与者:主应用程序和服务。确实,该服务是单身,但应用程序在列表中行动! 我假设服务是由外部实体调用的,当发生这种情况时,应用程序仍然可以运行吗?在这种情况下是否存在并发???

三江源

2 个答案:

答案 0 :(得分:1)

关于第2点,您可以使用Concurrent Collections来管理所需的大部分线程安全。

我不确定你在第1点的意思。听起来你在描述基本的polymorphism,但也许你可以用一个例子来澄清吗?

编辑:在回答您对Sixto的回答时,请考虑使用WCF的sessions。从你所描述的内容来看,听起来像WCF服务应该坐在一个单独的主机应用程序上。您当前使用的应用程序应该具有对服务的服务引用,并且使用会话将能够调用模拟您使用当前客户端应用程序定义的列表实例化服务的要求的操作。

将此与我对暴露允许与此列表进行交互的操作的评论相结合,您将能够运行多个客户端计算机,处理会话存储列表?

希望这个解释得很好。

答案 1 :(得分:1)

将构造函数添加到MyService以传递列表肯定会按预期工作。就像我在对问题的评论中所说的那样,ServiceHost只会永远包含MyService类的单个实例,因此列表不会被共享,因为只有一个服务实例会使用它。

我会看一下dependency injector (DI) container让WCF做你正在尝试的事情。让DI容器为您的服务提供单例列表实例。另外@ Smudge202绝对正确,使用Concurrent Collection功能是实现列表所需的。

根据评论主题UPDATE:

DI方法可以通过从DI容器获取所有对象的依赖项而不是在代码中手动创建它们来实现。作为应用程序启动的一部分,您注册容器将提供的所有类型。当应用程序(或WCF)需要一个新的对象实例时,它会从容器中请求它,而不是“新建”它。例如,Castle Windsor WCF integration library实现了从容器中为WCF提供服务实例所需的所有连线。如果要推送自己的WCF集成,请使用WCF posts explains the details of how to use the Microsoft Unity DI container

此问题中引用的共享列表将作为应用程序中已实例化的对象在容器中注册。从DI容器中旋转WCF服务实例时,将提供所有构造函数参数,包括对共享列表的引用。关于依赖注入和控制反转的信息很多,但this Martin Fowler article是一个很好的起点。