c#進程之間對象傳遞方法

來源:互聯網
上載者:User

標籤:thread   app   hal   oid   入口   void   href   images   實現   

1. 起源

KV項目下載底層重構升級決定採用獨立進程進行Media下載處理,以能做到模組複用之目的,因此涉及到了獨立進程間的資料傳遞問題。

目前進程間資料傳遞,多用WM_COPYDATA、共用dll、記憶體映射、Remoting等方式。相對來說,WM_COPYDATA方式更為簡便,網上更到處是其使用方法。

而且Marshal這個靜態類,其內建多種方法,可以很方便實現字串、結構體等資料在不同進程間傳遞。

那麼,對象呢?如何傳遞? 

 

2、序列化

想到了,Newtonsoft.Json.dll這個神器。相對於內建的XmlSerializer這個東西,我更喜歡用Json。

那麼,如此處理吧,我們來建個Demo解決方案,裡面有HostApp、ClildApp兩個項目,以做資料傳遞。 

 

3、ChildApp項目

先說這個,我沒有抽取共用的資料單獨出來,而做為Demo,直接寫入此項目中,HostApp引用此項目,就可引用其中public出來的資料類型。

資料結構部分代碼:

    [StructLayout(LayoutKind.Sequential)]    public struct COPYDATASTRUCT    {        public IntPtr dwData;        public int cbData;        [MarshalAs(UnmanagedType.LPStr)]        public string lpData;    }    public class Person    {        private string name;        private int age;        private List<Person> children;        public Person(string name, int age)        {            this.name = name;            this.age = age;            this.children = new List<Person>();        }        public string Name        {            get { return this.name; }            set { this.name = value; }        }        public int Age        {            get { return this.age; }            set { this.age = value; }        }        public List<Person> Children        {            get { return this.children; }        }        public void AddChildren()        {            this.children.Add(new Person("liuxm", 9));            this.children.Add(new Person("liuhm", 7));        }        public override string ToString()        {            string info = string.Format("姓名:{0},年齡:{1}", this.name, this.age);            if (this.children.Count != 0)            {                info += (this.children.Count == 1) ? "\r\n孩子:" : "\r\n孩子們:";                foreach (var child in this.children)                    info += "\r\n" + child.ToString();            }            return info;        }    }

 

表單代碼:

    public partial class ChildForm : Form    {        public const int WM_COPYDATA = 0x004A;        private IntPtr hostHandle = IntPtr.Zero;        Person person = new Person("liujw", 1999);        [DllImport("User32.dll", EntryPoint = "SendMessage")]        private static extern int SendMessage(            IntPtr hWnd,               // handle to destination window            int Msg,                   // message            int wParam,                // first message parameter            ref COPYDATASTRUCT lParam  // second message parameter        );        public ChildForm(string[] args)        {            InitializeComponent();            if (args.Length != 0)                this.hostHandle = (IntPtr)int.Parse(args[0]);        }        private void btnSubmit_Click(object sender, EventArgs e)        {            this.person.Name = txtName.Text;            int age;            this.person.Age = int.TryParse(txtAge.Text, out age) ? age : 0;            this.person.AddChildren();            if (this.hostHandle != IntPtr.Zero)            {                string data = GetPersionStr();                COPYDATASTRUCT cds = new COPYDATASTRUCT();                cds.dwData = (IntPtr)901;                cds.cbData = data.Length + 1;                cds.lpData = data;                SendMessage(this.hostHandle, WM_COPYDATA, 0, ref cds);            }        }        private string GetPersionStr()        {            return JsonConvert.SerializeObject(this.person);        }    }

這樣在表單按鈕btnSubmit_Click事件中,完成了資料向HostApp的字串形式傳遞。


如何擷取宿主程式的視窗控制代碼呢?改造下ChildApp的Program.cs過程即可:

        /// <summary>        /// 應用程式的主進入點。        /// </summary>        [STAThread]        static void Main(string[] args)        {            Application.EnableVisualStyles();            Application.SetCompatibleTextRenderingDefault(false);            Application.Run(new ChildForm(args));        }

 

3、HostApp項目

我們權且稱之為宿主專案吧,其表單代碼為:

    public partial class MainForm : Form    {        public const int WM_COPYDATA = 0x004A;        public MainForm()        {            InitializeComponent();        }                protected override void WndProc(ref Message m)        {            base.WndProc(ref m);            switch (m.Msg)            {                case WM_COPYDATA:                    COPYDATASTRUCT copyData = new COPYDATASTRUCT();                    Type type = copyData.GetType();                    copyData = (COPYDATASTRUCT)m.GetLParam(type);                    string data = copyData.lpData;                    RestorePerson(data);                    break;            }        }        private void RestorePerson(string data)        {            var person = JsonConvert.DeserializeObject<Person>(data);            if (person != null)                txtInfo.Text = person.ToString();        }        private void btnSubmit_Click(object sender, EventArgs e)        {            RunChildProcess();        }        private void RunChildProcess()        {            string appPath = Path.GetDirectoryName(Application.ExecutablePath);            string childPath = Path.Combine(appPath, "ChildApp.exe");            Process.Start(childPath, this.Handle.ToString());        }    }

它的作用就是接收子進程傳遞迴來的字串,用JsonConvert還原序列化為Person對象。

是不是很簡單呢?

其實就是用了WM_COPYDATA的字串傳遞功能,加上Json的序列化、還原序列化,而實現c#不同進程間的對象傳遞

 

4、:

 

 Json參考:http://www.newtonsoft.com/json

c#進程之間對象傳遞方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.