2010-11-13 35 views
0

我有一個網格形式。網格有一個上下文菜單,其中一個菜單項應該爲網格中選定的每個項目創建報告。不過,我希望這些報告在單獨的線程上運行,並且在點擊報告項目後立即關閉上下文菜單。我仍然試圖理解這個全線程的東西。以下是我到目前爲止。這是發生了什麼事。當我點擊上下文菜單項時,會出現上下文菜單,然後出現第一個報告,暫停,然後出現第二個報告,暫停等。但是,上下文菜單直到最後纔會消失報告顯示。我並不擔心報告之間的暫停,但它看起來像是在同步處理。我主要想知道爲什麼上下文菜單不會立即消失。如何在.NET中異步運行報告?

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

號線正在這裏創建,ShowChainOfCustodyReport()運行在UI線程上。沒關係,當你真正創建一個線程時,它不太可能正常工作。 – 2010-11-13 19:00:56

回答

0

「如果多個BeginInvoke的調用都在同一的DispatcherPriority做,他們將在調用的時間順序執行。」從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()沒有被阻塞。

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