Я делаю несколько тестов с удаленным взаимодействием .net и обнаружил, что при использовании делегата с ним возникает проблема.
У меня есть одно приложение, которое одновременно является сервером и клиентом. Когда пользователь запускает приложение из проводника в первый раз, оно запускается как сервер и запускает новый процесс как клиент. Оба работают нормально. Теперь, когда пользователь запускает его снова, пока процессы сервера и клиента все еще работают, он должен стать клиентом и отправить сообщение на сервер о новом запущенном процессе, а затем завершиться.
Все работает хорошо, за исключением того, что делегат выполняется в серверном процессе, а не в клиенте.
Вот код.
const string PIPE_NAME = "testPipeName33";
const string OBJECT_NAME = "test";
static RemoteObject remoteObject;
static void RegisterClient()
{
IpcClientChannel chan = new IpcClientChannel();
ChannelServices.RegisterChannel(chan, false);
remoteObject = (RemoteObject)Activator.GetObject(typeof(RemoteObject),
string.Format("ipc://{0}/{1}", PIPE_NAME, OBJECT_NAME));
}
static void RegisterServer()
{
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IpcServerChannel chan = new IpcServerChannel("", PIPE_NAME, serverProvider);
ChannelServices.RegisterChannel(chan, false);
RemotingServices.Marshal(new RemoteObject(), OBJECT_NAME);
}
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if ((args.Length == 0 || args[0] == "s"))
{
try
{
RegisterServer();
}
catch (RemotingException)
{
// try to register it with the pipe name. If it fails, means server is already running.
//bad idea, I know, but it's just for barebone quick test
RegisterClient();
remoteObject.OnNewProcessStarted("test");
Application.Exit();
return;
}
Process.Start(Application.ExecutablePath, "c");
Application.Run(new Form1("Server"));
}
else
{
IsClient = true;
RegisterClient();
remoteObject.SetOnNewProcessStarted(OnNewProcessStarted);
Application.Run(new Form1("Client"));
}
}
static bool IsClient = false;
static bool OnNewProcessStarted(string commandLine)
{
MessageBox.Show("Is Client : " + IsClient);//problem here, IsClient should be true
return true;
}
Класс удаленного объекта.
public delegate bool OnNewProcessStartedDelegate(string text);
internal class RemoteObject : MarshalByRefObject
{
public OnNewProcessStartedDelegate OnNewProcessStartedHandler;
public bool OnNewProcessStarted(string commandLine)
{
if (OnNewProcessStartedHandler != null)
return OnNewProcessStartedHandler(commandLine);
return false;
}
public void SetOnNewProcessStarted(OnNewProcessStartedDelegate onNewProcessStarted)
{
OnNewProcessStartedHandler = onNewProcessStarted;
}
public override object InitializeLifetimeService()
{
return null;
}
}
PS: Может быть только один сервер и один клиент.
s
, или сервер уже запущен. Опубликованный код завершен, вы можете запустить его на своей стороне. - person J. Doe   schedule 27.09.2015