【发布时间】:2011-02-11 16:31:53
【问题描述】:
以下场景:
在 WPF 应用程序中,程序调用 Log.Write 将消息排入队列,这些消息将写入另一个线程中的不同输出(DB、文件)。写入的数据集数量可以从少量到 50000 或更多条目不等。用户每次都可以关闭应用程序。为了确保即使用户尝试在 Application.Exit 上关闭应用程序也能写入所有数据,从 UI 线程调用 Log.Dispose 函数。 UI 线程加入后台线程等待所有数据写入。这发生在 Application.Exit 上。
现在在此过程中显示进度对话框会很棒。问题是,进度并没有随着以下代码移动:
// Initialize
Log.CurrentInstance.DisposingProgress += new EventHandler<DisposingEventArgs>(Log_DisposingProgress)
// initialize dialog
// ...
_dialog.Show();
Log.Dispose(); // in this method data is written back, threads closed and so on
protected void SetPercentage(DisposingEventArgs e)
{
if (e.DisposingCompleted)
_dialog.Close();
_dialog.Value = e.Percentage;
}
// this function is called by a timer which checks the status of the disposing process
protected void Log_DisposingProgress(object sender, DisposingEventArgs e)
{
_dialog.Dispatcher.Invoke(new Action<DisposingEventArgs>(SetPercentage), e);
}
我猜这个问题是因为我从 UI 线程调用 Log.Dipose。所以我尝试用
调用 Log.Disposenew Action(Log.Dispose).BeginInvoke(null, null);
如果我在按钮单击等事件上调用 Dispose 并且应用程序仍在运行,这将使进度条移动。如果我从 Application.Exit 调用它,我必须阻止应用程序关闭。我试试
new Thread(() => { while(_isDisposing) Thread.Sleep(100); }
但在这种情况下进度条仍然没有移动。
我尝试启动另一个 UI 线程,其中应该显示进度对话框,但程序将关闭。因为当我调用Dispatcher.Run()时,仍然会处理关闭调用。
【问题讨论】:
-
您是否考虑过记录更改并在程序启动时进行更新?换句话说,不是阻止应用程序完全关闭,而是在程序关闭后运行时执行它。
-
我不知道如何跟踪这些变化?似乎这个任务的复杂性很高,只是为了写回日志记录。即使它可能很多。也许我误解了你的想法。
标签: c# .net wpf multithreading dispatcher