How can a self-hosted (WinForm ) WCF service interact with the main form?

前端 未结 3 468
借酒劲吻你
借酒劲吻你 2020-12-10 09:33

Simplified version of what I\'m trying to achieve:

  • I have a WinForms app that runs hidden (Visible = false) in the background.
  • It\'s got only one Form
相关标签:
3条回答
  • 2020-12-10 10:01

    Using this method you have completely a thread-safe application, and you don't have any limitation.

    Service Contract Definition

    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        void DisplayAlert();
    }
    

    Service Implementation

    public class Service:IService
    {
        public void DisplayAlert()
        {
            var form = Form1.CurrentInstance;
            form.MySynchronizationContext.Send(_ => form.Show(), null);
        }
    }
    

    Program.cs

    [STAThread]
    static void Main()
    {        
        var host = new ServiceHost(typeof (Service));
        host.Open();
    
        Application.SetCompatibleTextRenderingDefault(false);
        Application.EnableVisualStyles();
        Application.Run(new Form1());
     }
    

    Form Implementation

    public partial class Form1 : Form
    {
        public static Form1 CurrentInstance;
        public SynchronizationContext MySynchronizationContext;
        private bool showForm = false;
    
        public Form1()
        {
            InitializeComponent();
            MySynchronizationContext = SynchronizationContext.Current;
            CurrentInstance = this;
        }
    
        // use this method for hiding and showing if you want this form invisible on start-up
        protected override void SetVisibleCore(bool value)
        {
            base.SetVisibleCore(showForm ? value : showForm);
        }
    
        public void Show()
        {
            showForm = true;
            Visible = true;   
        }
    
        public void Hide()
        {
            showForm = true;
            Visible = true;
        }
    }
    

    Client

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Press Enter to show form");
            Console.ReadLine();
    
            var client = new ServiceClient();
            client.DisplayAlert();
        }
    }
    
    0 讨论(0)
  • 2020-12-10 10:04

    Can you use a singleton for your service? If so you could implement it like this:

    [ServiceContract]
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    public class MyClass : IMyClass
    {
        Form1 _f;
        public MyClass(Form1 f)
        {
            _f = f;
        }
    
        [OperationContract]
        public void Alert(string mess)
        {
            _f.Text = mess;
        }
    }
    

    Then when you setup your service host, you instantiate it and pass it the form:

    MyClass c = new MyClass(this);
    string baseAddress = "http://localhost:12345/Serv";
    var host = new ServiceHost(c, new Uri(baseAddress));
    
    0 讨论(0)
  • 2020-12-10 10:22

    In my opinion the answer is "simpol" as a friend says. First of all I would not even bother to follow the path described by you, after all a web service provides all the necessary means to communicate with it. Between your Form1 (which host your service) and your hosted service add a client (where client code is hosted by same Form1) and allow your client to communicate with your service using a duplex channel. In this way your client will know if a message was sent to your service by initiating a a long running request and being notified through the callback. Here is a link with a fancy article related to duplex channels: http://blogs.msdn.com/b/carlosfigueira/archive/2012/01/11/wcf-extensibility-transport-channels-duplex-channels.aspx

    P.S: This is a rough suggestion to get you started which for sure can be improved.

    0 讨论(0)
提交回复
热议问题