我有类似下面的代码,我正面临UI Hung问题,没有直接的方法来重现它。它随机发生1次10次。我无法确定导致问题的原因。
我有下面的按钮点击代码,它会显示一个子窗口: -
private void processCart_Click(object sender, RoutedEventArgs e)
{
// processcart is Child Window Like Dialog To Open on Top Of Main Window
processcart = new ProcessCart();
processcart.Closed += ProcessCart_OnClosed;
// Disable Parent Window
this.Dispatcher.Invoke(new Action(() =>
{
try
{
this.IsEnabled = false;
}
catch (Exception ex)
{ }
}));
processcart.Owner = Window.GetWindow(this);
// Openning Child Window
processcart.Show();
}
private void ProcessCart_OnClosed(object sender, EventArgs e)
{
// On Child Window Close Doing some UI Update on Main Window
totalChangeAmount.Dispatcher.Invoke(new Action(() =>
{
try
{
totalChangeAmount.Text = XFuelMath.roundingTwo(cart.ChangeTotal) + "";
}
catch
{ }
}));
// Starting Background Worker Thread for Database operation.
if (!bgwTransaction.IsBusy)
{
bgwTransaction.RunWorkerAsync(cart);
}
}
private void bgwTransaction_DoWork(object sender, DoWorkEventArgs e)
{
// Doing some database operation but no UI Operation
// I dont know if i can call task inside background worker.
Task.Run(() => DeleteCurrentTicketDataFromDB(dataList, false));
// Calling another background worker inside it
if (!bgwPrintRecipt.IsBusy)
{
bgwPrintRecipt.RunWorkerAsync();
}
}
private void bgwPrintRecipt_DoWork(object sender, DoWorkEventArgs e)
{
// Sending Data to printer
}
private void bgwPrintRecipt_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// No Ui Operation Here
}
private void bgwTransaction_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Some UI Operation
totalSurcharge.Dispatcher.Invoke(() =>
{
totalSurcharge.Text = "0";
});
saleNumber.Dispatcher.Invoke(() => { });
saleDataGrid.Dispatcher.Invoke(new Action(() =>
{
try
{
saleDataGrid.ItemsSource = currentSharedTicketCollection;
saleDataGrid.Items.Refresh();
if (isautoscroll && item!=null)
{
saleDataGrid.ScrollIntoView(item, saleDataGrid.Columns[0]);
saleDataGrid.SelectedItem = item;
}
}
}));
// Enable the parent window Again
this.Dispatcher.Invoke(new Action(() =>
{
try
{
this.IsEnabled = true;
}
catch (Exception ex)
{ }
}));
}
我不确定我是否在BackgroundWorker
和DoWork
内拨打RunWorkerCompleted
。
请指导我在此代码中需要更改的内容?
答案 0 :(得分:1)
您应该在processCart_Click处理程序中删除Dispatcher调用,这将在同一个UI线程中执行,除非您在创建的不同线程中有多个WPF窗口,否则根本不需要。
除此之外,您应该将调试器附加到挂起的进程并查看它挂起的位置。如果在执行它的计算机上没有安装调试器,则可以右键单击任务管理器并创建转储文件。该文件可以加载到Visual Studio中。
如果您的应用程序是在Windows x64上执行的32位应用程序,则需要关闭任务管理器并从C:\ Windows \ SysWOW64 \ Taskmgr.exe启动一个以在64位Windows上进行32位转储。如果不这样做,则无法将其加载到具有托管调用堆栈的VS中。