[C#]Process.Exited事件觸發的執行緒會受Process.SynchronizingObject屬性設定的影響

[C#]Process.Exited事件觸發的執行緒會受Process.SynchronizingObject屬性設定的影響

最近在用Process時才發現自己對於Process類別實在不是很熟,本來以為在主執行緒將Process叫起來後關閉,Process.Exited事件會被導回主執行緒去觸發,後來才發現並不是那麼一回事,這邊以一個簡單的範例來看:


using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication13
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			var process = Process.Start("calc.exe");
			process.EnableRaisingEvents = true;
			process.Exited += new EventHandler(process_Exited);
			textBox1.Text = "Main Thread ID:" + Thread.CurrentThread.ManagedThreadId.ToString();
			Console.Read();
		}

		void process_Exited(object sender, EventArgs e)
		{
			MessageBox.Show("Process Thread ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
		}
	}
}

 

程式啟動時會順帶開啟計算機程式,並秀出主執行緒ID。

image

 

關閉計算機程式時會顯示出所在的執行緒ID,從下圖可以看出執行緒ID並不一樣,Process.Exited被帶到另外個執行緒了。

image

 

後來詢問網友才發現原來Process.Exited事件觸發的執行緒會受Process.SynchronizingObject屬性設定的影響,這在MSDN中的Process.Exited 事件也有稍稍提到。

image

 

MSDN把這個細節寫在Process.SynchronizingObject 屬性那邊。

image

 

裡面也有提到說如果是透過工具列將Process元件加入使用的話,Visual Studio會幫你自動設定SynchornizingObject屬性。

image

 

這邊試著加入SynchornizingObject屬性設定後再跑一次。


using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication13
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			var process = Process.Start("calc.exe");
			process.EnableRaisingEvents = true;
			process.Exited += new EventHandler(process_Exited);
			process.SynchronizingObject = this;
			textBox1.Text = "Main Thread ID:" + Thread.CurrentThread.ManagedThreadId.ToString();
			Console.Read();
		}

		void process_Exited(object sender, EventArgs e)
		{
			MessageBox.Show("Process Thread ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
		}
	}
}

 

Process.Exited觸發的動作就會被帶回到主執行緒。

image

 

這邊筆者還是有點Confuse,基本上Process離開時多半人預想都是回到主執行緒,而多半在使用時也都是帶入表單讓它帶回主執行緒,甚至透過工具列使用Process元件也是自動設定讓它帶回主執行緒,那做這樣的設計實在有些奇怪,也許是因為實作上有些限制而採取這樣的設計吧。

 

Link