【发布时间】:2017-11-03 10:40:42
【问题描述】:
在我的应用程序中有三个线程,例如:
private Thread _analysisThread;
private Thread _head2HeadThread;
private Thread _formThread;
每个线程都以如下方式启动:
if (_analysisThread == null || !_analysisThread.IsAlive)
{
_analysisThread = new Thread(() => { Analysis.Logic(match); });
_analysisThread.Start();
}
我有一个 ListView,用户可以在其中选择一个项目,然后重新启动线程,但我想防止这种情况发生,因为每个线程内的方法都很繁重,所以需要时间来完成它们。
到目前为止,我想禁用 ListView 选择,所以我做到了:
<ListView IsEnabled="{Binding IsMatchListEnabled}">
private bool _isMatchListEnabled = true;
public bool IsMatchListEnabled
{
get { return _isMatchListEnabled; }
set
{
_isMatchListEnabled = value;
OnPropertyChanged();
}
}
在新线程开始之前我会:IsMatchListEnabled = false;,但我需要做的是检查所有线程是否已完成,然后执行:IsMatchListEnabled = true;,实际上如果我在所有线程之后启用ListView,我会得到ListView 甚至启用了,因为Thread 代码是异步的,而Thread 之外的代码是同步的,所以实际上这个属性是没有用的。
我试图避免这种情况是创建一个这样的无限循环:
while (true)
{
if (!_analysisThread.IsAlive && !_head2HeadThread.IsAlive && !_formThread.IsAlive)
{
IsMatchListEnabled = true;
break;
}
}
这个循环被放置在所有线程执行之后,但正如你所想象的那样,这将冻结应用程序。 有什么解决办法吗?
【问题讨论】:
-
使用
Tasks 代替线程。Task提供正常的等待完成方式。如果您坚持,您可以使用 Threads 做到这一点,但没有太多理由这样做。 -
@Evk 是的,谢谢你的提示:
-
您编写了即发即弃的线程代码。你几乎永远不会忘记。不要使用 Thread,使用方便的帮助类来帮助你不要忘记。 BackgroundWorker,Task,也许是 async/await。并且一定要仔细阅读这一点,当你理解得不够透彻时,穿线会把你活活吃掉并吐出你的骨头。
标签: c# multithreading