我正在编写一个特殊的数据结构,它将在.NET库中可用,并且该数据结构的一个特性是线程安全的,前提是只有一个线程向其写入数据,并且只有一个线程从中读取数据它(读者线程和作者线程可以不同).
问题是如何强制所有Read操作都由同一个线程执行?
我的解决方案是捕获System.Threading.Thread.ManagedThreadID并在第一次读取时将其存储在私有成员中.然后,在后续读取时检查ManagedThreadID与已保存的ManagedThreadID,如果它们不同则抛出异常.
这还不够,或者是否有一种不同的更可靠的机制来做到这一点.
注意:要求此库在没有Windows.Forms上下文的情况下可用.
这与之前的问题有关.
我现在想要了解的是如何防止UI线程异常终止应用程序,而非UI异常不能.
供参考,请参阅此示例.
最重要的是,在这种情况下我希望能够"静默地"终止进程 - 不显示Windows对话框,询问我是否要发送错误报告.
这是我的AppDomain UnhandledExceptionHandler:
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
// Maybe do some logging here if allowed
}
catch
{
}
// then just terminate the application
Application.Exit();
}
Run Code Online (Sandbox Code Playgroud)
更新
根据本回答中的评论,我想澄清一点,最重要的是,我想了解更多关于使UI线程尽早通过该Application.ThreadException机制捕获未处理异常的机制.是否可以在非UI线程上实现此类行为.
我正在使用Windbg(具有sos扩展),并尝试调试崩溃的应用程序。我能够转储引发异常的调用的IL,并且通过检查代码,如果可以转储评估堆栈的内容,似乎可以获得所需的信息。WinDbg&sos可以做什么?
这是我所做的:
!token2ee theModuleName 0600009a (其中,ModuleName是我正在调试的应用程序(和程序集)的名称,9a是Windows错误报告工具报告的崩溃方法的方法偏移量。我得到以下输出:
模块:000e2c3c(theApplicationName.exe)
令牌:0x0600009a方法描述
:000e67c8
名称:MyNamespace.MyClassName.theCulpritFn(MyOtherClass)
JITTED代码地址:0081b1d0
!dumpil 00e67c8 (为相关方法转储了IL)。这是输出:
// ..
// .. the previous code omitted for brevity
.catch
{
IL_0071: stloc.0
IL_0072: nop
IL_0073: ldstr "Can't set CurrentServer property for: "
IL_0078: ldarg.0
IL_0079: ldfld MyNamespace.MyClassName::_currentServer
IL_007e: brtrue.s IL_0087
IL_0080: ldstr ""
IL_0085: br.s IL_0092
IL_0087: ldarg.0
IL_0088: ldfld MyNamespace.MyClassName::_currentServer
IL_008d: callvirt MyNamespace.MyOtherClass::get_Name
IL_0092: call System.String::Concat
IL_0097: ldloc.0
IL_0098: newobj MyNamespace.MySpecialExceptionType::ctor …Run Code Online (Sandbox Code Playgroud)我现在应该知道这一点,但是,如果下面两个陈述之间有什么区别呢?
嵌套连接:
SELECT
t1.*
FROM
table1 t1
INNER JOIN table2 t2
LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
ON t2.table2_ID = t1.table1_ID
Run Code Online (Sandbox Code Playgroud)
更传统的加入:
SELECT
t1.*
FROM
table1 t1
INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID
LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
Run Code Online (Sandbox Code Playgroud) 所以这是我的情况,以及我提出的解决问题的解决方案.我创建了一个包含TinyMCE的应用程序,允许用户创建用于发布的HTML内容.用户可以在其标记中包含图像,并拖动/调整影响IMG标记中最终宽度/高度属性的图像.这一切都很棒,用户可以包含图像并将它们调整大小/重新定位到所需的外观.但是一个大问题是我现在向客户端发送一个(可能)更大的图像,只是让浏览器将图像调整为请求的宽度/高度属性.所有带宽和丢失的加载时间....
所以我的解决方案是预处理我的用户标记内容,扫描所有IMG标记并解析出Height/Width/Src属性.然后将每个img的SRC标记设置为phpThumb请求,并将解析后的Height/Width传递到缩略图URL.这将创建缩小尺寸的图像(以CPU和缓存为代价优化带宽).您对此解决方案有何看法?我已经看过其他帖子,人们使用mod_rewrite做类似的事情,但我想影响页面服务上的内容,而不是在收到图片请求时操纵它们.....对这个设计的任何想法?
我需要一些精细细节的帮助,因为我的正则表达式技能需要一些工作,但我的时间很短,并承诺尽快支付我的技术知识债务.为了使正则表达式更容易,我可以肯定一些事情.只有需要此处理的img标签才会有一个width =""height =""属性(使用双引号和较低的套接文本,但我认为如果TinyMCE更改,匹配文本不区分大小写会更好)
所以正则表达式只匹配必要的Img标签,也许还有另外三个正则表达式来提取src,宽度和高度?
感谢大家.
我从WPF应用程序获取报告,该应用程序部署在字段中,在尝试显示打开文件对话框时引发以下ArgumentException.
Exception Message: Value does not fall within the expected range.
Method Information: MS.Internal.AppModel.IShellItem2 GetShellItemForPath(System.String)
Exception Source: PresentationFramework
Stack Trace
at MS.Internal.AppModel.ShellUtil.GetShellItemForPath(String path)
at Microsoft.Win32.FileDialog.PrepareVistaDialog(IFileDialog dialog)
at Microsoft.Win32.FileDialog.RunVistaDialog(IntPtr hwndOwner)
at Microsoft.Win32.FileDialog.RunDialog(IntPtr hwndOwner)
at Microsoft.Win32.CommonDialog.ShowDialog(Window owner)
...
Run Code Online (Sandbox Code Playgroud)
问题是到目前为止我还没有能够在我的开发环境中复制这个问题,但我收到了一些来自该领域的报告,说明发生了这种异常.
谁看过这个吗?最重要的是你知道原因和/或修复它,除了简单地在它周围放一个try/catch并指示用户再试一次他们试图做的事情吗?
在回复注释时,这是打开对话框的代码(不,这不是检查返回类型的问题).从ShowDialog中抛出异常(请参阅堆栈跟踪):
Nullable<bool> result = null;
var dlg = new Microsoft.Win32.OpenFileDialog();
dlg.DefaultExt = ".txt";
dlg.Filter = "Text Files (.txt)|*.txt|All Files|*.*";
dlg.Title = "Open File";
dlg.Multiselect = false;
dlg.InitialDirectory = GetFolderFromConfig("folders.templates");
result = dlg.ShowDialog(Window.GetWindow(this));
if (result == true)
{
// Invokes another method here.. …Run Code Online (Sandbox Code Playgroud) 我有一个主菜单,mnuMainMenu包括几个子菜单.其中一个子菜单mnuMostRecentDirs本身是另一个菜单,它使用绑定到ObservableCollection的ItemSource属性在运行时生成它的项目.基本上它显示最近使用的文件夹列表.
问题是添加的MenuItems动态生成以下数据绑定错误:
主菜单的XAML声明如下:
<!-- Main Menu -->
<Menu x:Name="mnuMainMenu" Height="Auto" IsMainMenu="True">
<!--- ... more menu declarations before ... -->
<MenuItem x:Name="mnuitemWorkDirs" Header="Directories">
<MenuItem x:Name="mnuNewDir"
Header="New"
Style="{StaticResource MenuItem}"
Command="{x:Static cmds:Commands.NewDirectory}" />
<MenuItem x:Name="mnuCurrentDir"
Header="Current"
Style="{StaticResource MenuItem}"
Command="{x:Static cmds:Commands.CurrentDirectory}" />
<MenuItem x:Name="mnuMostRecentDirs"
Header="Recent Directories.."
Style="{StaticResource MenuItem}"
ItemsSource="{Binding ElementName=theMain, Path=MostRecentFoldersList}" />
</MenuItem>
<!--- ... more menu declarations after ... -->
</Menu>
Run Code Online (Sandbox Code Playgroud)
以下代码在运行时将文件夹添加到observable集合:
private void PopulateMostRecentFoldersList(string[] paths)
{
MostRecentFoldersList.Clear(); …Run Code Online (Sandbox Code Playgroud) 有没有办法更新包含在PrintQueue对象中的打印队列状态信息?
我试过在PrintQueue对象上调用Refresh,但这并没有真正做任何事情。例如,我已经关闭了打印机,并且控制面板正确地将打印机显示为“离线”,但是QueueStatus属性以及 IsOffline 属性并未反映这一点 - 无论我在两者上调用 Refresh 多少次有问题的PrintServer和PrintQueue。
我已经看到了如何使用 WMI 查询获取状态信息的示例,但我想知道 - 因为这些属性在PrintQueue对象上可用- 是否有任何方法可以使用这些属性。
我的应用程序中有后台线程.当其中一个线程获得未处理的异常时,整个CLR退出.
这是正常的行为,还是CLR中的错误?
我希望线程会退出,但CLR将继续工作.
我有一个WPF组合框,我绑定了一些东西.用户必须选择其中一个项目.如果他们没有选择任何内容,我想发出警告并让用户重新选择.
怎么办?
我正在考虑使用"选择"按钮.当用户没有选择任何内容时,我设置:
if (combobox.SelectedItem == null)
{
MessageBox.Show("Please select one");
//Here is the code to go back to selection
}
Run Code Online (Sandbox Code Playgroud)
这个要求有通用的解决方案吗?
提前致谢.