我有一个带网格的表单。网格具有上下文菜单,其中一个菜单项应为网格中选择的每个项目创建报告。但是,我希望报表在单独的线程上运行,并且在单击报表项后几乎立即关闭上下文菜单。我仍然试图理解整个线程的事情。以下是我到目前为止的情况。这是正在发生的事情。当我单击上下文菜单项时,显示上下文菜单,然后出现第一个报告,暂停,然后出现第二个报告,暂停等等。但是,上下文菜单直到最后一个才会消失报告显示。我并不是真的担心报告之间的暂停,但它看起来确实是同步处理的。我主要想知道为什么上下文菜单不会立即消失。
void custodyRptItem_Click(object sender, RoutedEventArgs e)
{
foreach (CustodyItem curItem in CustodyControl.SelectedItems)
{
Dispatcher.BeginInvoke((ShowReportDelegate)ShowChainOfCustodyReport, curItem);
}
}
void ShowChainOfCustodyReport(CustodyItem item)
{
CustodyReport report = new CustodyReport(item);
report.Show();
}
答案 0 :(得分:0)
“如果在同一个DispatcherPriority上进行了多次BeginInvoke调用,它们将按照调用的顺序执行。”来自http://msdn.microsoft.com/en-us/library/ms591206.aspx
即使BeginInvoke立即返回,所有委托都在创建Dispatcher的线程上执行,因此它们是同步执行的(相互之间)。
我假设Dispatcher来自GUI线程,这就是为什么在所有报告表单显示之前上下文菜单不会消失的原因 - 消息泵在消息之前处理有关执行ShowChainOfCustodyReport的消息以使菜单消失。顺便说一下,在GUI线程上调用ShowChainOfCustodyReport是好的,因为你不想在非GUI线程上调用report.Show()或至少没有消息泵的线程。
您想要“异步”执行此操作的唯一原因是在报告显示之前菜单消失了吗?您是否尝试在Dispatcher.Invoke()之前在上下文菜单上调用Hide()(不确定这是否可行,暂时没有使用上下文菜单...)。如果这确实有效,你可以删除所有Dispatcher.BeginInvoke代码,直接调用report.Show(),因为Show()没有阻塞。
答案 1 :(得分:0)
您可以使用TreadPool:
void custodyRptItem_Click(object sender, RoutedEventArgs e)
{
foreach (CustodyItem curItem in CustodyControl.SelectedItems)
{
ThreadPool.QueueUserWorkItem(ShowChainOfCustodyReport, curItem);
}
}
void ShowChainOfCustodyReport(object context)
{
CustodyItem item = context as CustodyItem;
if (item == null) return;
if (InvokeRequired)
{
Action<object> a = ShowChainOfCustodyReport;
Invoke(a, context);
}
else
{
CustodyReport report = new CustodyReport(item);
report.Show();
}
}