C#子線程使用FolderBrowserDialog的問題延伸

來源:互聯網
上載者:User

本文轉自:http://www.diybl.com/course/4_webprogram/asp.net/asp_netxl/2007125/90477.html

Q:子線程如何使用FolderBrowserDialog 

A:

private void button1_Click(object sender, EventArgs e)
        ...{
            System.Threading.Thread s = new System.Threading.Thread(new System.Threading.ThreadStart(test));
            s.ApartmentState = System.Threading.ApartmentState.STA;
            s.Start();
        }

        public void test()
        ...{
            System.Windows.Forms.FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.ShowDialog();
        }

以上代碼簡單的示範了FolderBrowserDialog在子線程中的使用,其中設定線程的ApartmentState為System.Threading.ApartmentState.STA是關鍵的語句。在.net2.0中應該使用

s.SetApartmentState(System.Threading.ApartmentState.STA);

 如果沒有上述設定會報如下錯誤

在可以調用 OLE 之前,必須將當前線程設定為單一執行緒 Apartment(STA)模式。

如果你瞭解com的執行緒模式的話,應該已經清楚上面的問題根本了。
我們先看一下 FolderBrowserDialog的實現方法,這個控制項實現是通過ole的.可以用Reflector.exe看一下他的代碼,調用了幾個windows shell32的api。

[SuppressUnmanagedCodeSecurity]
internal class Shell32
...{
    // Methods
    public Shell32();
    [DllImport("shell32.dll", CharSet=CharSet.Auto)]
    public static extern IntPtr SHBrowseForFolder([In] UnsafeNativeMethods.BROWSEINFO lpbi);
    [DllImport("shell32.dll")]
    public static extern int SHCreateShellItem(IntPtr pidlParent, IntPtr psfParent, IntPtr pidl, out FileDialogNative.IShellItem ppsi);
    public static int SHGetFolderPathEx(ref Guid rfid, uint dwFlags, IntPtr hToken, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszPath, uint cchPath);
    [DllImport("shell32.dll", EntryPoint="SHGetFolderPathEx")]
    private static extern int SHGetFolderPathExPrivate(ref Guid rfid, uint dwFlags, IntPtr hToken, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszPath, uint cchPath);
    [DllImport("shell32.dll")]
    public static extern int SHGetMalloc([Out, MarshalAs(UnmanagedType.LPArray)] UnsafeNativeMethods.IMalloc[] ppMalloc);
    [DllImport("shell32.dll", CharSet=CharSet.Auto)]
    public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);
    [DllImport("shell32.dll")]
    public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);
    [DllImport("shell32.dll")]
    public static extern int SHILCreateFromPath([MarshalAs(UnmanagedType.LPWStr)] string pszPath, out IntPtr ppIdl, ref uint rgflnOut);
}

 

COM提供的執行緒模式共有三種:Single-Threaded Apartment(STA 單線程套間)、Multithreaded Apartment(MTA 多線程套間)和Neutral Apartment/Thread Neutral Apartment/Neutral Threaded Apartment(NA/TNA/NTA 中立線程套間,由COM+提供)。

STA 一個對象只能由一個線程訪問,相當於windows的訊息迴圈,實現方式也是通過訊息迴圈的,ActiveX控制項、OLE文檔伺服器等有介面的,都使用STA的套間。MTA 一個對象可以被多個線程訪問,即這個對象的代碼在自己的方法中實現了線程保護,保證可以正確改變自己的狀態。

所以建立和訪問一個activex或者ole對象時,必須設定線程模式為sta。

稍微有些多線程使用經驗的人會發現用Control.Invoke方法也可以成功調用ole對象,比如上面的例子改為

private void Form1_Load(object sender, EventArgs e)
        ...{
            System.Threading.Thread s = new System.Threading.Thread(new System.Threading.ThreadStart(test));
            //s.SetApartmentState(System.Threading.ApartmentState.STA);
            s.Start();
        }

        public delegate void dtest();

        public void test()
        ...{
            this.Invoke(new dtest(invokeTest));
        }

        public void invokeTest()
        ...{
            System.Windows.Forms.FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.ShowDialog();
        }

   

             其實使得這個調用成功的原因不是在於Invoke,還是線程模式。如果把main函數上邊的[STAThread] 去掉的話,文章開始處的錯誤仍然會發生。Invoke只是讓主線程來執行子線程的調用函數。[STAThread]在程式入口處即將主線程置為sta模式,如果沒有這句話將置為mta模式。而且執行緒模式一旦確定將不可以更改,所以你無法在其他地方用代碼來設定主線程的執行緒模式。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.