代码改变世界

.NET Remoting Basic(9)-上下文(CallContext)

2010-08-26 22:59  Clingingboy  阅读(801)  评论(0编辑  收藏  举报

   CallContext 是类似于方法调用的线程本地存储区的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽。
使用该功能,存储对象必须实现ILogicalThreadAffinative接口

1.定义接口

[Serializable]
 public class LogSettings: ILogicalThreadAffinative
 {
    public bool EnableLog;
 }


2.客户端设置一个对象

static void Main(string[] args)
 {
     String filename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
     RemotingConfiguration.Configure(filename);
 
    if (args.Length > 0 && args[0].ToLower() == "/enablelog")
    {
       LogSettings ls = new LogSettings();
       ls.EnableLog = true;
       CallContext.SetData("log_settings", ls);
    }
 
    IRemoteCustomerManager mgr = 
       (IRemoteCustomerManager) RemotingHelper.CreateProxy(typeof(IRemoteCustomerManager));
    Customer cust = mgr.GetCustomer(42);
 
    Console.WriteLine("Done");
     Console.ReadLine();
 }    


3.服务器端接收对象

根据key获取对象,然后判断属性

class CustomerManager: MarshalByRefObject, IRemoteCustomerManager
   {
       public Customer GetCustomer(int id)
       {
         LogSettings ls = CallContext.GetData("log_settings") as LogSettings;
         
         if (ls!= null && ls.EnableLog)
         {
            // simulate write to a logfile 
            Console.WriteLine("LOG: Loading Customer " + id);
         }
 
           Customer cust = new Customer();
           return cust;
       }
   }
 
    class ServerStartup
    {
        static void Main(string[] args)
        {
            String filename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            RemotingConfiguration.Configure(filename);
            Console.WriteLine ("ServerStartup.Main(): Server started");
            Console.ReadLine();
        }
    }


4.将客户端和服务器端上下文数据操作进行封装

因为上下文数据可以在客户端和服务器端同时交互,所以可以进行封装,而无需让客户端和服务器端知道细节

4.1 定义LogSettingContext类

public class LogSettingContext
 {
    public static bool EnableLog
    {
       get
       {
          LogSettings ls = CallContext.GetData("log_settings") as LogSettings;
       
          if (ls!= null)
          {
             return ls.EnableLog;
          }
          else
          {
             return false;
          }
       }
       set
       {
          LogSettings ls = new LogSettings();
          ls.EnableLog = value;
          CallContext.SetData("log_settings", ls);
       }
    }
 }

4.2 前端调用

LogSettingContext.EnableLog=true;

4.3后端调用

if (LogSettingContext.EnableLog)
 {
    // simulate write to a logfile 
    Console.WriteLine("LOG: Loading Customer " + id);
 }

如此便简化了操作