如何在.NET中异步运行报表?

时间:2010-11-13 18:53:53

标签: c# multithreading asynchronous reportviewer

我有一个带网格的表单。网格具有上下文菜单,其中一个菜单项应为网格中选择的每个项目创建报告。但是,我希望报表在单独的线程上运行,并且在单击报表项后几乎立即关闭上下文菜单。我仍然试图理解整个线程的事情。以下是我到目前为止的情况。这是正在发生的事情。当我单击上下文菜单项时,显示上下文菜单,然后出现第一个报告,暂停,然后出现第二个报告,暂停等等。但是,上下文菜单直到最后一个才会消失报告显示。我并不是真的担心报告之间的暂停,但它看起来确实是同步处理的。我主要想知道为什么上下文菜单不会立即消失。

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();
}

2 个答案:

答案 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();
        }
    }