.NET远程处理层(Remoting)是一个比较古老的概念吧,Framework 1.0就存在。远程处理是两个对象跨应用程序域进行通信的行为,两个对象可以在同一计算机,也可以不在;在同一计算机也可以存在于不同的进程和应用程序域(AppDomain)

优点:

  • 便于我们进行分布式开发
  • TCP通道的Remoting速度非常快
  • 虽然是远程的,但是非常接近于本地调用对象
  • 可以做到保持对象的状态
  • 没有应用程序限制,可以是控制台,Windows Form,IIS,Windows服务承载远程对象

缺点:

  • 属于非标准的应用,因此有平台限制
  • 脱离IIS的话需要有自己的安全机制

公共DLL中定义的消息类:(定义在公共DLL中,供客户端和服务器端引用,避免循环编译依赖)
[code=’c#’]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RemotingLibrary
{
public class RemoteMessageObject : MarshalByRefObject
{
private int m_MessageCount = 0;

public RemoteMessageObject()
{
Console.WriteLine(“Constructing RemoteMessageObject.”);
}

public void DisplayMessage(string message)
{
m_MessageCount++;
Console.WriteLine(“[{0}]Message is: {1}”, m_MessageCount.ToString(), message);
}

public string ReturnMessage()
{
return “Remoting Server Message Count: ” + m_MessageCount.ToString();
}
}
}
[/code]

服务器端:
[code=’c#’]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
using RemotingLibrary;

namespace CLRRemoting
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“========= Server Started =======”);

HttpChannel c = new HttpChannel(30001);
ChannelServices.RegisterChannel(c, false);

RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteMessageObject),
“RemoteMessageObject.soap”,
WellKnownObjectMode.Singleton);
Console.ReadLine();
}
}
}
[/code]

客户端:
[code=’c#’]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels;
using RemotingLibrary;

namespace RemotingClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“========= Client Started =======”);
HttpChannel c = new HttpChannel();
ChannelServices.RegisterChannel(c, true);

object remoteObject = Activator.GetObject(
typeof(RemoteMessageObject),
“http://itsserver2:30001/RemoteMessageObject.soap”);
RemoteMessageObject sample = remoteObject as RemoteMessageObject;
if (sample != null)
{
for (int i = 0; i < 10; i++) { sample.DisplayMessage("Client Message" + i.ToString()); Console.WriteLine(sample.ReturnMessage()); } Console.ReadLine(); } } } } [/code] 代码简单,就不介绍了。我把Server部署在局域网远程的服务器上。 远程对象被定义为WKO,只有在第一次访问的时候才构造。5分钟没有访问对象时,远程对象会被垃圾收集器收集,再次访问的时候,编号和构造函数都重新开始。 我的想法,我最近想写一个比较大的东西,最近在仔细研究WCF,估计Remoting将是我的并行程序的核心。

熟悉微软技术的同学都知道,.NET 3.0的核心技术是这么几个:

  • WPF:Windows Presentation Foundation
  • WCF:Windows Communication Foundation
  • WF:Windows Workflow Foundation
  • WCS:Windows CardSpace
  • LINQ

为什么Windows Workflow Foundation简称叫WF,而不是WWF呢?
原因是,Microsoft不想与World Wrestling Federation(世界摔跤联盟)和World Wildlife Fund(世界野生动植物基金会)发生关系~

Sysinternals总是出些好东西。今天去小强那里又看到一个。这个Windows Sysinternals Desktops,是类似,不是类似,就是,Windows下的像Linux一样能虚拟出4个桌面来的东东。
软件设置,我设置成Ctrl+1,Ctrl+2,Ctrl+3,Ctrl+4,俗称,换枪~

[singlepic=15906]

最终就是四个独立的桌面,不熟悉这个右下角图标,还真不知道是虚拟桌面,很很安全哦~

[singlepic=15905]

对了,支持包括Vista在内的各种系统,而且很小,绿色软件62KB。岂不是完美?
美中不足是,在Vista下只有第一个虚拟桌面可以用Aero效果,其他的都是Basic。不过不耽误事儿。

这里下载:
http://technet.microsoft.com/en-us/sysinternals/cc817881.aspx

这是《编程之美——微软技术面试心得》里的第一个题,后来我推荐到微软亚洲研究院的一个实习生面试的时候做的正是这个题。
其实这个题难度适中,现在机器都是多核CPU,照书里的答案去做早就不行了。
下面我给出一个适用于双核CPU上在两个核都形成正弦曲线的做法吧。

[code=’c#’]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace CPU
{
public class Sin1ThreadParam
{
public int AffinityMask = 0x00000000;

public Sin1ThreadParam(int AffinityMask)
{
this.AffinityMask = AffinityMask;
}
}

class Sin1
{
public void DoWork(object o)
{
Sin1ThreadParam param = o as Sin1ThreadParam;
if (param != null)
{
// 设置线程CPU亲和性
IntPtr nHD = new IntPtr(Thread.CurrentThread.ManagedThreadId);
Win32.SetThreadAffinityMask(nHD, param.AffinityMask);

// 采样率
const double SPLIT = 0.01;
// 采样总数
const int COUNT = 200;
const double PI = 3.14159265;
// 扫描速度,控制曲线波长
const int INTERVAL = 300;

// 忙循环时间长度
int[] busySpan = new int[COUNT];
// 闲循环时间长度
int[] idleSpan = new int[COUNT];
int half = INTERVAL / 2;
// X
double radian = 0.0;

// 构成一个具有COUNT个采样点的忙、闲循环
for (int i = 0; i < COUNT; i++) { busySpan[i] = (int)((half + (Math.Sin(PI * radian) * half))); idleSpan[i] = INTERVAL - busySpan[i]; radian += SPLIT; } int startTime = 0; int j = 0; // 按照忙闲循环比率跑死循环和Sleep while (true) { j = j % COUNT; startTime = Environment.TickCount; while ((Environment.TickCount - startTime) <= busySpan[j]) { } Thread.Sleep(idleSpan[j]); j++; } } } } } [/code] 调用的时候用两个线程去跑,分别用Windows API的SetThreadAffinityMask指定不同的CPU亲和性。 [code='c#'] using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Diagnostics; using System.Runtime.InteropServices; namespace CPU { class Win32 { [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] public static extern int SetThreadAffinityMask(IntPtr hWnd, int nIndex); } class Program { static void Main(string[] args) { Sin1 sin11 = new Sin1(); Thread t1 = new Thread(new ParameterizedThreadStart(sin11.DoWork)); Sin1ThreadParam p1 = new Sin1ThreadParam(0); Thread t2 = new Thread(new ParameterizedThreadStart(sin11.DoWork)); Sin1ThreadParam p2 = new Sin1ThreadParam(1); t1.Start(p1); t2.Start(p2); } } } [/code] 结果是这样子的: [singlepic=15904]