首页 软件 购物 网址 万年历 阅读 | 天天财汇 | 开发教程 头条阅读
图片批量下载器 M3U8下载器 网页批量下载器 图片自动播放器 淘宝下载 屏幕截图器 网页截图器 超级按键
喔哦浏览器 一键清理系统垃圾 天天百宝箱 布谷鸟定时关机 豆豆文本编辑器 木马查杀 显示器测试 好听音乐
TxT小说阅读器 快马文件互传 小说家小说写作助手 FoxFile文件管理器 千寻小说下载 高山文件备份 网速测试 文字转语音大师
股价下载分析器 离线地图下载器 多播视频 漫多多 品妙游戏 打豆豆 俄罗斯方块 果蔬连连看 宠物连连看 美女连连看 五子棋 订制软件
推荐分类: 软件公告 | 焦点关注 | 天天财汇 |
  当前位置: 首页 > 软件公告 > 技术专区 > 子线程使用FolderBrowserDialog的问题延伸 > 正文显示
  百分百防木马的网页浏览器 网虫浏览器
 翻页: [1]   共1/1页
第1楼: 子线程使用FolderBrowserDialog的问题延伸  
   作者: 匿名   发表时间: 2008/8/25 21:58:15   主页:   IP: 保密
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 之前,必须将当前线程设置为单线程单元(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模式。而且线程模型一旦确定将不可以更改,所以你无法在其他地方用代码来设置主线程的线程模型。

http://blog.csdn.net/jinjazz/archive/2007/11/29/1907240.aspx  

 翻页: [1]   共1/1页



   若有疑问请联系我们

  ※软件公告※
图片批量下载器
获首届软件创新大赛优秀奖
电脑教育报
专访TxT小说阅读器
软件相关
·软件公告
·图片批量下载器
·超级按键
·网虫浏览器
·一键清除系统垃圾
·TxT小说阅读器
·热门小说推荐
·小说下载器
·网页截图器
·木马祼奔
·天天百宝箱
·显示器测试
·图片管理器
·好听音乐盒
·连连看游戏系列
资讯相关
·焦点关注
·在线游戏
·娱乐八卦
·经济论坛
·体育世界
·健康知识
·每日一笑
·技术专区
·特别推荐
·随便贴贴
三石聚峰
Intel软件合作伙伴
·几张很黄很黄的图片
·预测你的未来潜能

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/22 12:43:13-

 网站联系 2006-2024 三石聚峰 WWW.3FWork.COM 蜀ICP备06016416号