首页 > 解决方案 > DDE 服务器示例中的 C# System.Reflection.TargetInvocationException

问题描述

我用计时器制作了一个 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 已启动。mscorlib.dll中的错误信息'System.Reflection.TargetInvocationException'出来了,进程停止在Advise(" ", " ");

Advise() 和 _Timer 中也没有 Invoke() 方法。请帮我解决问题。谢谢。

标签: c#ndde

解决方案


看起来你有一些收容/寿命问题。该表单创建了一个 theDdeServer,然后 theDdeServer 创建了主表单的不同实例(但从不显示它)。那看起来不对。您可能希望在构建时将表单传递给服务器

但最可能的原因是表单创建了 theDdeServer,然后立即处理它:

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

  }
}

using块的右括号处,.Net 将破坏您的服务器。你不想在using这里使用 a 。相反,您希望表单保留在服务器上……然后在处理表单时将其删除。就像是:

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 */

}

推荐阅读