处理来自另一个应用程序的事件

本文关键字:事件 应用程序 另一个 处理 | 更新日期: 2023-09-27 18:03:09

Hellu

这个问题很简单,但答案似乎五花八门,非常不清楚。

在应用程序A中,我如何处理应用程序B发送的事件,以及如何在B中实现这些事件知道B不知道A.的存在

假设B是一个"批处理"类型的程序,在后面做事情,没有任何图形显示,而a是一个很好的GUI(双关语(,它应该写B在对话框或其他东西中发送给他的消息。

我发现了一些有趣的答案(比如这个或这个(,但没有一个真正回答C#的问题;充其量,它们会重定向到一些外部工具。

我听说这是C#中的一个问题,但最终,有一个干净的方法可以做到吗?谢谢

如果这可以简化事情,假设A启动B(使用Process或其他东西(,知道B也可以单独启动(在这种情况下,我不需要整个事件处理(。

处理来自另一个应用程序的事件

您可以使用MemoryMappedFileMutexEventWaitHandle的组合来管理进程之间的关系。

以下示例显示了它的工作方式。在实际代码中,producer()方法的应用程序与consumer()方法不同,但这说明了一种实现:

using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
    class Program
    {
        void run()
        {
            Task.Run(() => consumer());
            Task.Run(() => producer());
            Console.WriteLine("Press <ENTER> to stop.");
            Console.ReadLine();
        }
        static void producer()
        {
            using (var mmf = MemoryMappedFile.CreateOrOpen("MyMapName", 1024))
            using (var view = mmf.CreateViewStream())
            {
                var writer = new BinaryWriter(view);
                var signal = new EventWaitHandle(false, EventResetMode.AutoReset, "MyEventName");
                var mutex = new Mutex(false, "MyMutex");
                for (int i = 0; i < 100; ++i)
                {
                    string message = "Message #" + i;
                    mutex.WaitOne();
                    writer.BaseStream.Position = 0;
                    writer.Write(message);
                    signal.Set();
                    mutex.ReleaseMutex();
                    Thread.Sleep(1000);
                }
            }
        }
        static void consumer()
        {
            using (var mmf = MemoryMappedFile.CreateOrOpen("MyMapName", 1024))
            using (var view = mmf.CreateViewStream())
            {
                var reader = new BinaryReader(view);
                var signal = new EventWaitHandle(false, EventResetMode.AutoReset, "MyEventName");
                var mutex = new Mutex(false, "MyMutex");
                while (true)
                {
                    signal.WaitOne();
                    mutex.WaitOne();
                    reader.BaseStream.Position = 0;
                    var message = reader.ReadString();
                    Console.WriteLine("Received message: " + message);
                    mutex.ReleaseMutex();
                }
            }
        }
        static void Main()
        {
            new Program().run();
        }
    }
}

重要提示:此实现不使用队列,因此如果使用者在新消息到达之前不处理消息,则可能会错过消息。

如果不能错过任何消息,则必须使用某种排队实现,例如MSMQ。

但是,您也可以考虑使用Windows Communications Foundation,它允许您在另一个进程中调用远程方法,但这可能需要比您想要的更多的进程之间的耦合。

最后,另一种可能性是使用Named Pipe。事实上,我认为这可能是对你最好的解决方案。

这里有一个Microsoft示例,显示服务器和客户端IPC使用命名管道:http://msdn.microsoft.com/en-us/library/bb546085%28v=vs.110%29.aspx

取决于场景的复杂程度。你可以使用进程间通信,甚至是一些简单的文件(或数据库表(,这些文件将由两个应用程序写入/读取(你需要同步对它的访问(。