- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 Windows 窗体中有一个旧应用程序,它在许多地方对数据库进行一些搜索。有时这会花费很多时间,所以我决定在 wpf 中创建一个加载屏幕,以向用户显示某些内容正在单独的线程中加载。基本上它只是一个带有加载指示器(转圈)的全透明窗口。在我的主机和我的虚拟机上一切正常,但是当我尝试将它部署到我们的演示环境时它就像 - 它开始加载指示器显示,几秒钟后它消失并且应用程序永远停止响应。我的第一个想法是这是 GPU 加速的问题,它无法处理透明度,但它会显示几秒钟,所以这不是问题所在。所以很可能我做了坏事。下面您可以看到我的代码,您是否注意到可能有问题/导致死锁或其他问题?
public class LoadingManager
{
public LoadingManager()
{ }
public LoadingManager(string LoadingText)
{
loadingText = LoadingText;
}
private string loadingText = "Please wait ..";
private Thread thread;
private bool ThreadReadyToAbort = false;
private BusyIndicatorView loadingWindow;
public void BeginLoading()
{
this.thread = new Thread(this.RunThread);
this.thread.IsBackground = true;
this.thread.SetApartmentState(ApartmentState.STA);
this.thread.Start();
}
public void EndLoading()
{
if (this.loadingWindow != null)
{
this.loadingWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{ this.loadingWindow.Close(); }));
while (!this.ThreadReadyToAbort) { }; // I also tried to remove this while but it didn't help
}
this.thread.Abort();
}
public void RunThread()
{
this.loadingWindow = new BusyIndicatorView();
loadingWindow.tbLoadingCaption.Text = loadingText;
this.loadingWindow.Closing += new System.ComponentModel.CancelEventHandler(waitingWindow_Closed);
this.loadingWindow.ShowDialog();
}
void waitingWindow_Closed(object sender, System.ComponentModel.CancelEventArgs e)
{
Dispatcher.CurrentDispatcher.InvokeShutdown();
this.ThreadReadyToAbort = true;
}
编辑。
我注意到在这台机器上,当我第一次点击搜索时,它通常(有时它在第一次点击时也会失败)工作。如果我再次单击它会显示一秒钟而不是消失并且应用程序停止响应。所以看起来 Thread 没有关闭,Dispatcher 关闭失败?但是没有抛出异常......
最佳答案
您的 BeginLoading 方法在完成之前可以被多次调用,因此可以创建多个 wpf 窗口。这搞乱了各种引用资料。也不要中止线程,让它自己决定。以下是两个更改:
public void BeginLoading()
{
this.thread = new Thread(this.RunThread);
this.thread.IsBackground = true;
this.thread.SetApartmentState(ApartmentState.STA);
this.thread.Start();
while (this.loadingWindow == null) { } // <--- Add this line
}
public void EndLoading()
{
if (this.loadingWindow != null)
{
this.loadingWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{ this.loadingWindow.Close(); }));
while (!this.ThreadReadyToAbort) { };
}
//this.thread.Abort(); // <-- Remove this line
}
此外,如果这只是为了繁忙的屏幕,我会说必须有比这更好、更安全的方法。出于学术目的,这是一个有趣的问题,但不是生产代码,特别是如果一些初级开发人员将来可能会摆弄这个问题。
编辑:如果我减少重复调用 BeginLoading 和 EndLoading 之间的延迟,我的机器仍然会崩溃。可能与wpf窗口如何异步关闭有关。我删除了 Closed 事件处理程序,只使用了一个 bool 标志来指示窗口是否“已加载”,我没有看到任何问题:
public class LoadingManager2
{
public LoadingManager2()
{ }
public LoadingManager2(string LoadingText)
{
loadingText = LoadingText;
}
private string loadingText = "Please wait ..";
private Thread thread;
private MyWindow loadingWindow;
private bool isLoaded = false;
public void BeginLoading()
{
this.thread = new Thread(this.RunThread);
this.thread.IsBackground = true;
this.thread.SetApartmentState(ApartmentState.STA);
this.thread.Start();
while (!this.isLoaded) { };
}
public void RunThread()
{
this.loadingWindow = new MyWindow();
this.isLoaded = true;
this.loadingWindow.ShowDialog();
}
public void EndLoading()
{
this.loadingWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{
this.loadingWindow.Close();
this.isLoaded = false;
}));
while (this.isLoaded) { };
}
}
关于c# - 在单独线程中加载屏幕的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31624396/
我正在开发一个需要能够平均三个数字的 Facebook 应用程序。但是,它总是返回 0 作为答案。这是我的代码: $y = 100; $n = 250; $m = 300; $number = ($y
我只是无法弄清楚这一点,也找不到任何对我来说有意义的类似问题。我的问题:我从数据库中提取记录,并在我的网页上以每个面板 12 条的倍数显示它们。因此,我需要知道有多少个面板可以使用 JavaScrip
我是一名优秀的程序员,十分优秀!