我刚用这个纠正了一个bug:
_Thread.SetApartmentState(ApartmentState.STA);
Run Code Online (Sandbox Code Playgroud)
现在我想了解它的含义,以及它的工作原理!
我想要两个主题.我们打电话给他们:
线程A触发事件,线程B侦听此事件.当执行线程B事件侦听器时,它是用线程A的线程ID执行的,所以我猜它是在线程A中执行的.
我想做的是能够向线程B发起事件,例如:"嘿,数据已准备就绪,你现在可以处理它".此事件必须在其自己的Thread中执行,因为它使用只有他可以访问的内容(如UI控件).
我怎样才能做到这一点 ?
谢谢你的帮助.
我们在Winforms应用程序中有一个标准文本框,它在我们的开发环境中以正常方式(即粘贴)响应粘贴(右键单击菜单和CTRL + V).
在一个客户站点,粘贴大部分被完全忽略(表现得好像剪贴板中没有任何内容).我们使用TextBox的单行和多行版本测试了它,我们创建了一个只有几个TextBox的独立应用程序,在这个客户端站点上问题仍然存在.粘贴大部分都不起作用.
在进一步的测试中,我们发现只需在测试winforms应用程序中询问剪贴板的内容,它就会返回为空字符串.用记事本双重检查,我们发现剪贴板中确实有一些东西.
这是我们检查的内容:
请记住,完全相同的已编译应用程序始终在我们的开发机器上成功粘贴,并且偶尔会成功粘贴到客户的计算机上!这就是它如此神秘的原因.
在所有情况下,我们都通过粘贴到我们的应用程序旁边的记事本来验证剪贴板中有什么东西.
还有其他人看过这个和/或可以提出解释吗?
更新/进一步调查
它可能与线程有关吗?我们不会对线程做任何有趣的事情,我们也不必担心使用STAThread属性.但是MSDN页面说:
Clipboard类只能在设置为单线程单元(STA)模式的线程中使用.要使用此类,请确保使用STAThreadAttribute属性标记Main方法.
因此,在没有主线程的Winforms项目中 - 只是一个启动表单,你在哪里放置这个属性?为什么我们不在开发机器上需要它?为什么我们永远不需要在我们制作的无数其他Winforms应用程序中使用它?
我的任务是使用任务获取目录图标并将其显示在DataGridView中(我正在执行搜索文件夹).为此,我使用SHGetImageList WinAPI函数.我有一个帮助类如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace WindowsFormsApplication6 {
public class Helper {
private const uint ILD_TRANSPARENT = 0x00000001;
private const uint SHGFI_SYSICONINDEX = 0x000004000;
private const uint SHGFI_ICON = 0x000000100;
public static readonly int MaxEntitiesCount = 80;
public static void GetDirectories(string path, List<Image> col, IconSizeType sizeType, Size itemSize) {
DirectoryInfo dirInfo = new DirectoryInfo(path);
DirectoryInfo[] dirs = dirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly);
for (int i = 0; i < dirs.Length …Run Code Online (Sandbox Code Playgroud) 我试图在Unity中的C#中读取剪贴板中的文本,然后将其设置为变量.
我看过这篇文章,但它似乎在Unity中不起作用:https: //msdn.microsoft.com/en-us/library/kz40084e(v = vs.110).aspx
我只想阅读纯文本.没有图像或任何东西.我还发现了一些其他文章,但Unity中的代码都不起作用.
我正在尝试使用 CommonOpenFileDialog 的文件夹选择器,如本答案中所述。问题是,即使有一个非常精简的示例项目,我在尝试使用 CommonOpenFileDialog 的函数时也会遇到异常ShowDialog()。
using Microsoft.WindowsAPICodePack.Dialogs;
namespace DialogTest
{
class Program
{
public static void Main(string[] args)
{
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
if (result == CommonFileDialogResult.Ok)
{
//Do Stuff
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还与作者 Microsoft 一起使用以下 nuget 包:
此代码在 处产生以下异常dialog.ShowDialog();:
System.Runtime.InteropServices.COMException was unhandled
ErrorCode=-2147023116
HResult=-2147023116
Message=A null reference pointer was passed to the stub. (Exception from HRESULT: …Run Code Online (Sandbox Code Playgroud) 我设法在C#中编写了一个相对较大的WinForms应用程序,它在没有方法[STAThread]属性的情况下正常运行Main().
为了实现这一点,我必须覆盖很多WinForms功能(例如使用自定义BeginInvoke和Invoke函数),使用自定义消息循环代替Application.Run,使用自定义文件对话框代替OpenFileDialog和SaveFileDialog,并使用WM_DROPFILES进行拖放而不是WinForms开箱即用的OLE方法.这都是"科学".
现在我想测试从所有GUI线程中省略STAThreadAttribute对性能的任何影响.我对Control类内部使用的COM配置知之甚少,无法预测这种影响.执行速度可能取决于哪个线程正在调用内部COM对象Control.
不可否认,我无法提出可以测试性能影响的基准测试[STAThread],因为我不确定哪些功能/操作会受到这种变化的影响(特别是与Control课程有关).
我该怎么找?如果有的话,Control我应该通过省略哪些操作/方法运行得更快/更慢[STAThread]?
附录:基本原理是我正在慢慢迁移我的应用程序以使用自定义窗口系统(出于可移植性的原因,主要是因为在Linux上使用Mono,其WinForms实现并不完整),所以我不得不自己重写很多功能.仅仅是巧合,我注意到我已经覆盖了如此多的功能,我可以省略[STAThread],一切都会按预期工作.
我期望由于COM编组调用ThreadPool(配置为MTA)和GUI线程(默认情况下应配置为STA)导致性能发生变化.ThreadPool由于在不同的线程公寓中配置了来自GUI线程的调用,因此需要进行编组,这会引入同步开销.通过将GUI线程保留为MTA,应该减少编组,因此可能更快地执行函数调用.我想以务实的方式测试这个主张.