C# 線程的掛起與恢複

來源:互聯網
上載者:User

標籤:c#   thread   suspend   resume   

我本質是不希望有人去掛起或恢複線程的,因為沒人知道線程到底執行到了那裡,

掛起線程後再恢複線程可能會造成某些問題,然後你容易無法解決它,所以微軟

如今是把Thread.Resume()與Thread.Suspend()過時,不久以後會移除出.NET庫

但是移除你就無法掛起或恢複了嗎?我想是不可能 畢竟辦法如此之多 好了我們回

到正題 如果你有必要這樣做我也希望你們用AutoResetEvent(自動重設單事件對象)

的配合,因為它會很安全 但是能否夠安全還需要具體看開發人員自己的代碼如何寫的。

        private void Form1_Load(object sender, EventArgs e)        {            Thread fd_thr = new Thread(this.FileDownload);            fd_thr.Start();            fd_thr.Suspend(); // 掛起線程, 過時            fd_thr.Resume();  // 恢複線程, 過時        }        private void FileDownload()        {            byte[] buffer = null;            using (WebClient client = new WebClient())                buffer = client.DownloadData("http://www.baidu.com");            Console.WriteLine(Encoding.UTF8.GetString(buffer));        }
下面的代碼,貌似沒有問題,但你可能會在輸出面板會出現一句錯誤“引發的異常:

“System.IO.IOException”(位於 mscorlib.dll 中)”那麼這就會涉及到一個問題,我本

人是討厭代碼拋出錯誤的,首先你要知道一但拋出錯誤意味著無法釋放資源且不

說最重要拋出錯誤的頻率過高你的程式意味著穩定性極差不一會可能就會自己掛

掉,每次拋出錯誤意味著一次堆疊溢位,try catch盡量少用,為什麼需要自己體會

        private AutoResetEvent fd_thr_supend = new AutoResetEvent(false);        private void Form1_Load(object sender, EventArgs e)        {            Thread fd_thr = new Thread(this.FileDownload);            fd_thr.Start();            this.fd_thr_supend.Reset(); // 掛起線程            this.fd_thr_supend.Set(); // 恢複線程        }        private void FileDownload()        {            byte[] buffer = null;            using (WebClient client = new WebClient())                buffer = client.DownloadData("http://www.baidu.com");            this.fd_thr_supend.WaitOne(); // 阻塞,等待訊號            Console.WriteLine(Encoding.UTF8.GetString(buffer));        }
上面則配合AutoResetEvent方式配合進行線程的掛起或恢複,這樣做有利代碼的

安全與減少發生錯誤的幾率,因為你不是真正的把線程掛起而是阻塞線程 那麼一

旦發生錯誤 你可以儘早的排查錯誤,而不是因為Thread.Resume()與Thread.Sus

pend()方式一掛起,一旦發生錯誤你根本找不到錯誤的原因,大大的增加了穩定

性與安全性。

        [DllImport("kernel32.dll", SetLastError = true)]        private static extern int GetCurrentThreadId();        [DllImport("kernel32.dll", SetLastError = true)]        private static extern int SuspendThread(IntPtr hThread);        [DllImport("kernel32.dll", SetLastError = true)]        public static extern uint ResumeThread(IntPtr hThread);        public int hCurrenthThreadId;        [DllImport("kernel32.dll", SetLastError = true)]        public static extern IntPtr OpenThread(int dwDesiredAccess, bool bInheritHandle, uint dwThreadId);        public const int THREADACCESS_SUSPEND_RESUME = 0x0002;        private void Form1_Load(object sender, EventArgs e)        {            Thread fd_thr = new Thread(this.FileDownload);            fd_thr.Start();            while (this.hCurrenthThreadId == 0); // 等待線程被啟動            IntPtr hCurrenthThread = OpenThread(THREADACCESS_SUSPEND_RESUME, false, (uint)this.hCurrenthThreadId);            // 掛起線程            SuspendThread(hCurrenthThread);            // 恢複線程            ResumeThread(hCurrenthThread);         }        private void FileDownload()        {            this.hCurrenthThreadId = GetCurrentThreadId();            byte[] buffer = null;            using (WebClient client = new WebClient())                buffer = client.DownloadData("http://www.baidu.com");            Console.WriteLine(Encoding.UTF8.GetString(buffer));        }
上面的方法也不安全,因為上面的做法其實與Thread.Resume()與Thread.Suspend()兩個函數的

功能差不多,不過是用於代替過時命令的一種Winapi方案,當然還有一些辦法。總之掛起或恢複

一個線程的辦法並不少 上面的三種方法其實都可以 不過需要考慮穩定性才是真。



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.