C # System.Reflection.TargetInvocationException в примере сервера DDE - PullRequest
0 голосов
/ 12 декабря 2018

Я сделал образец сервера DDE с таймером.

using System;
using System.Windows.Forms;
using NDde.Server;
using System.Timers;

namespace DDEServer_Test
{
    public partial class DDEServer_MainForm : Form
    {
        public DDEServer_MainForm()
        {
            InitializeComponent();
        }
        public void runDDEServer()
        {
            try
            {
                using (DdeServer server = new theDDEServer("dde_server"))
                {
                    server.Register();
                }
            }
            catch (Exception ex)
            {

            }
        }
        public void dispServerName(string serverName = "")
        {
            if (textBox1.InvokeRequired)
            {
                textBox1.Invoke((MethodInvoker)delegate { textBox1.Text = serverName; });
            }
            else
            {
                this.textBox1.Text = serverName;
            }
            //this.textBox1.Text = serverName;
        }
        public void dispTopicName(string topicName = "")
        {
            if (textBox2.InvokeRequired)
            {
                textBox2.Invoke((MethodInvoker)delegate { textBox2.Text = topicName; });
            }
            else
            {
                this.textBox2.Text = topicName;
            }
            //this.textBox2.Text = topicName;
        }
        public void dispItemName(string itemName = "")
        {
            if (textBox3.InvokeRequired)
            {
                textBox3.Invoke((MethodInvoker)delegate { textBox3.Text = itemName; });
            }
            else
            {
                this.textBox3.Text = itemName;
            }
            //this.textBox3.Text = itemName;
        }
        public void dispHandleString(string handleString = "")
        {
            if (textBox4.InvokeRequired)
            {
                textBox4.Invoke((MethodInvoker)delegate { textBox4.Text = handleString; });
            }
            else
            {
                this.textBox4.Text = handleString;
            }
            //this.textBox4.Text = handleString;
        }
        public void dispFormatString(string formatString = "")
        {
            if (textBox5.InvokeRequired)
            {
                textBox5.Invoke((MethodInvoker)delegate { textBox5.Text = formatString; });
            }
            else
            {
                this.textBox5.Text = formatString;
            }
            //this.textBox5.Text = formatString;
        }
        public void dispCommandString(string commandString="")
        {
            if (textBox6.InvokeRequired)
            {
                textBox6.Invoke((MethodInvoker)delegate { textBox6.Text = commandString; });
            }
            else
            {
                this.textBox6.Text = commandString;
            }
            //this.textBox6.Text = commandString;
        }
        public void dispDataString(string dataString = "")
        {
            if (textBox7.InvokeRequired)
            {
                textBox7.Invoke((MethodInvoker)delegate { textBox7.Text = dataString; });
            }
            else
            {
                this.textBox7.Text = dataString;
            }
            //this.textBox7.Text = dataString;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            runDDEServer();
        }

        //class
        public sealed class theDDEServer : DdeServer
        {
            DDEServer_MainForm mainForm = new DDEServer_MainForm();
            private System.Timers.Timer _Timer = new System.Timers.Timer();

            public theDDEServer(string service) : base(service)
            {
                _Timer.Elapsed += this.OnTimerElapsed;
                _Timer.Interval = 1000;
                _Timer.SynchronizingObject = this.Context;
            }
            private void OnTimerElapsed(object sender, ElapsedEventArgs args)
            {
                Advise("*", "*");
            }

            public override void Register()
            {
                Console.WriteLine("R");
                base.Register();
                _Timer.Start();
            }
            public override void Unregister()
            {
                _Timer.Stop();
                base.Unregister();
            }
            protected override bool OnBeforeConnect(string topic)
            {
                Console.WriteLine("Before Connect");

                mainForm.dispServerName(base.Service);
                mainForm.dispTopicName(topic);
                mainForm.dispHandleString();
                mainForm.dispHandleString();
                mainForm.dispItemName();
                mainForm.dispFormatString();
                mainForm.dispCommandString();
                mainForm.dispDataString();
                return true;
            }
            protected override void OnAfterConnect(DdeConversation conversation)
            {
                Console.WriteLine("After Connect");
                mainForm.dispServerName(conversation.Service);
                mainForm.dispTopicName(conversation.Topic);
                mainForm.dispHandleString(conversation.Handle.ToString());
                mainForm.dispHandleString();
                mainForm.dispItemName();
                mainForm.dispFormatString();
                mainForm.dispCommandString();
                mainForm.dispDataString();
            }
            protected override void OnDisconnect(DdeConversation conversation)
            {
                Console.WriteLine("Disconnect");
                mainForm.dispServerName(conversation.Service);
                mainForm.dispTopicName(conversation.Topic);
                mainForm.dispHandleString(conversation.Handle.ToString());
                mainForm.dispItemName();
                mainForm.dispFormatString();
                mainForm.dispCommandString();
                mainForm.dispDataString();
            }
            protected override bool OnStartAdvise(DdeConversation conversation, string item, int format)
            {
                Console.WriteLine("Start Advise");
                mainForm.dispServerName(conversation.Service);
                mainForm.dispTopicName(conversation.Service);
                mainForm.dispHandleString(conversation.Handle.ToString());
                mainForm.dispItemName(item);
                mainForm.dispFormatString(format.ToString());
                mainForm.dispCommandString();
                mainForm.dispDataString();
                return format == 1;
            }
            protected override void OnStopAdvise(DdeConversation conversation, string item)
            {
                Console.WriteLine("Stop Advise");
                mainForm.dispServerName(conversation.Service);
                mainForm.dispTopicName(conversation.Service);
                mainForm.dispHandleString(conversation.Handle.ToString());
                mainForm.dispItemName(item);
                mainForm.dispFormatString();
                mainForm.dispCommandString();
                mainForm.dispDataString();
            }
            protected override ExecuteResult OnExecute(DdeConversation conversation, string command)
            {
                Console.WriteLine("Execute");
                mainForm.dispServerName(conversation.Service);
                mainForm.dispTopicName(conversation.Service);
                mainForm.dispHandleString(conversation.Handle.ToString());
                mainForm.dispItemName();
                mainForm.dispFormatString();
                mainForm.dispCommandString(command);
                mainForm.dispDataString();
                return ExecuteResult.Processed;
            }
            protected override PokeResult OnPoke(DdeConversation conversation, string item, byte[] data, int format)
            {
                Console.WriteLine("Poke");
                mainForm.dispServerName(conversation.Service);
                mainForm.dispTopicName(conversation.Service);
                mainForm.dispHandleString(conversation.Handle.ToString());
                mainForm.dispItemName(item);
                mainForm.dispFormatString(format.ToString());
                mainForm.dispCommandString();
                mainForm.dispDataString(data.Length.ToString());
                return PokeResult.Processed;
            }
            protected override RequestResult OnRequest(DdeConversation conversation, string item, int format)
            {
                Console.WriteLine("Request");
                mainForm.dispServerName(conversation.Service);
                mainForm.dispTopicName(conversation.Service);
                mainForm.dispHandleString(conversation.Handle.ToString());
                mainForm.dispItemName(item);
                mainForm.dispFormatString(format.ToString());
                mainForm.dispCommandString();
                mainForm.dispDataString();
                if (format == 1)
                {
                    return new RequestResult(System.Text.Encoding.ASCII.GetBytes("Now = " + DateTime.Now.ToString() + "\0"));
                }
                return RequestResult.NotProcessed;
            }
            protected override byte[] OnAdvise(string topic, string item, int format)
            {
                Console.WriteLine("Advise");
                mainForm.dispServerName(this.Service);
                mainForm.dispTopicName(topic);
                mainForm.dispHandleString(item);
                mainForm.dispItemName(item);
                mainForm.dispFormatString(format.ToString());
                mainForm.dispCommandString();
                mainForm.dispDataString();
                if (format == 1)
                {
                    return System.Text.Encoding.ASCII.GetBytes("Now = " + DateTime.Now.ToString() + "\0");
                }
                return null;
            }
            public void TargetInvocationException(Exception inner)
            {
                MessageBox.Show(inner.Message);
            }
        }
    }
}

После нажатия кнопки, чтобы запустить сервер DDE.Консоль напечатала «R», что означает, что она запустила Register (), и _Timer запустился.Появилось сообщение об ошибке «System.Reflection.TargetInvocationException» в mscorlib.dll, и процесс был остановлен на этапе Advise («», «»);

Invoke () нетМетод в Advise () и _Timer либо.Пожалуйста, помогите мне решить проблему.Спасибо.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

После следования инструкциям Клэя и измените код.Вот код, и он может работать без ошибок.

using System;
using System.Windows.Forms;
using NDde.Server;
using System.Timers;

namespace DDEServer_Test
{
    public partial class DDEServer_MainForm : Form
    {
        theDDEServer server;
        public DDEServer_MainForm()
        {
            InitializeComponent();
        }
        public void runDDEServer()
        {

            try
            {
                server = new theDDEServer("DDE_Server", this);
                server.Register();
            }
            catch (Exception ex)
            {
                MessageBox.Show("DDE Server registered failed.  " + ex.Message);
            }
        }
        private void DDEServer_MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (server.IsRegistered)
                server.Unregister();
            server.Dispose();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            runDDEServer();
        }
    }
    public sealed class theDDEServer : DdeServer
    {
        DDEServer_MainForm server_mainForm;
        private System.Timers.Timer _Timer = new System.Timers.Timer();

        public theDDEServer(string service, DDEServer_MainForm mainform) : base(service)
        {
            server_mainForm = mainform;
            _Timer.Elapsed += this.OnTimerElapsed;
            _Timer.Interval = 1000;
            _Timer.SynchronizingObject = this.Context;
        }
        private void OnTimerElapsed(object sender, ElapsedEventArgs args)
        {
            Console.WriteLine("Advise all");
            this.Advise("*", "*");
        }

        public override void Register()
        {
            Console.WriteLine("Register");
            base.Register();
            _Timer.Start();
        }
        public override void Unregister()
        {
            Console.WriteLine("Unregister");
            server_mainForm = null;
            _Timer.Stop();
            base.Unregister();
        }
        protected override bool OnBeforeConnect(string topic)
        {
            Console.WriteLine("OnBeforeConnect");
            return true;
        }
        protected override void OnAfterConnect(DdeConversation conversation)
        {
            Console.WriteLine("OnAfterConnect");
        }
        protected override void OnDisconnect(DdeConversation conversation)
        {
            Console.WriteLine("OnDisconnect");
        }
        protected override bool OnStartAdvise(DdeConversation conversation, string item, int format)
        {
            Console.WriteLine("OnStartAdvise");
            return format == 1;
        }
        protected override void OnStopAdvise(DdeConversation conversation, string item)
        {
            Console.WriteLine("OnStopAdvise");
        }
        protected override ExecuteResult OnExecute(DdeConversation conversation, string command)
        {
            Console.WriteLine("OnExecute");
            return ExecuteResult.Processed;
        }
        protected override PokeResult OnPoke(DdeConversation conversation, string item, byte[] data, int format)
        {
            Console.WriteLine("OnPoke");
            return PokeResult.Processed;
        }
        protected override RequestResult OnRequest(DdeConversation conversation, string item, int format)
        {
            Console.WriteLine("OnRequest");
            if (format == 1)
            {
                Console.WriteLine("Request item = " + item);
                return new RequestResult(System.Text.Encoding.ASCII.GetBytes("Now = " + DateTime.Now.ToString() + "\0"));
            }
            return RequestResult.NotProcessed;
        }
        protected override byte[] OnAdvise(string topic, string item, int format)
        {
            Console.WriteLine("OnAdvise");
            if (format == 1)
            {
                Console.WriteLine("Advise item = " + item);
                return System.Text.Encoding.ASCII.GetBytes("Now = " + DateTime.Now.ToString() + "\0");
            }
            return null;
        }
    }
}
0 голосов
/ 12 декабря 2018

Похоже, у вас есть проблемы с защитой / продолжительностью жизни.Форма создает theDdeServer, а затем theDdeServer создает другой экземпляр главной формы (но никогда не показывает его).Это не выглядит правильно.Возможно, вы захотите передать форму на сервер при создании

Но наиболее вероятной причиной является то, что форма создает theDdeServer, а затем немедленно удаляет его:

public void runDDEServer()
{
  try
  {
    using (DdeServer server = new theDDEServer("dde_server"))
    {
      server.Register();
    }
  }
  catch (Exception ex)
  {

  }
}

На закрывающей скобкеБлок using .Net уничтожит ваш сервер.Вы не хотите использовать using здесь.Вместо этого вы хотите, чтобы форма удерживалась на сервере ... и затем избавлялась от нее , когда форма удаляется .Что-то вроде:

public partial class DDEServer_MainForm : Form
{
  DdeServer server;

  /* snipped out code */

  public void runDDEServer()
  {
    try
    {
      server = new theDDEServer("dde_server", this);
      server.Register();
    }
    catch (Exception ex)
    {
      //--> you should definitely do something here. Print a message at least!
    }
  }

  /* snipped out code */

  //--> In the form designer, hook this method to the OnClosing event!
  private void closeForm(object sender, System.ComponentModel.CancelEventArgs e)
  {
      server.Unregister();
      server.Dispose();
  }
}

А затем в DdeServer примите форму в качестве аргумента конструктора:

public sealed class theDDEServer : DdeServer
{
  DDEServer_MainForm mainForm;
  System.Timers.Timer _Timer = new System.Timers.Timer();

  public theDDEServer(string service, Form mainForm) : base(service)
  {
    DDEServer_MainForm = mainForm;
    _Timer.Elapsed += this.OnTimerElapsed;
    _Timer.Interval = 1000;
    _Timer.SynchronizingObject = this.Context;
  }

  /* snipped out code */

  public override void Unregister()
  {
    DDEServer_MainForm =  null;
    _Timer.Stop();
    base.Unregister();
  }

  /* snipped out code */

}
...