利用管道Pipelines做程序間的通訊

wzwyc發表於2024-09-27

程式碼:

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Reflection;
using System.Threading;

namespace CgdataBase;

public class PipeController
{
    private static PipeController _instance;
    public static PipeController Instance => _instance ?? (_instance = new PipeController());

    private BackgroundWorker _worker;
    private NamedPipeServerStream _server;
    private CancellationTokenSource _cts;

    public event Action ActivateWindow;

    private string PipeName
    {
        get
        {
            var assembly = Assembly.GetExecutingAssembly().GetName();
            return assembly.Name + assembly.Version.ToString();
        }
    }

    public PipeController()
    {
        _worker = new BackgroundWorker();
        _worker.WorkerSupportsCancellation = true;
        _worker.DoWork += Worker_DoWork;
    }

    private async void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        _cts = new CancellationTokenSource();
        var token = _cts.Token;

        while (token.IsCancellationRequested == false)
        {
            try
            {
                using (_server = new NamedPipeServerStream(PipeName, PipeDirection.In))
                {
                    await _server.WaitForConnectionAsync(token);
                    Debug.WriteLine("Client connected.");

                    using (StreamReader sr = new StreamReader(_server))
                    {
                        var text = await sr.ReadLineAsync();

                        OnActivateWindow();
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
    }

    private void OnActivateWindow()
    {
        ActivateWindow?.Invoke();
    }

    public void Start()
    {
        _worker.RunWorkerAsync();
    }

    public void Stop()
    {
        _cts?.Cancel();
        _worker?.CancelAsync();
        _server?.Close();
    }

    public void WakeUpServer()
    {
        try
        {
            using (var pipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.Out))
            {
                pipeClient.Connect(100);
                Debug.WriteLine("Connected to pipe.");

                using (StreamWriter sw = new StreamWriter(pipeClient))
                {
                    sw.AutoFlush = true;
                    sw.WriteLine(DateTime.Now.ToString());
                    Thread.Sleep(100);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }
}

相關文章