我运行这个算法,当我在我的GUI上按停止时,它会挂起,然后我按下我的VS暂停,只是为了查看我的代码光标在哪里,它指向或者或多或少地在thread.join()上敲击。并且内部异常是线程正在等待或者睡眠......这种情况发生了大约30秒,并且GUI稍后正常工作..
如何让gui不挂起而让代码线程运行,一旦完成更改应该反映在GUI上
namespace ILS.PLMOptimization
{
public class PLMOptimizationLoop : Disposable
{
private Thread PLMOptimizerThread;
private AutoResetEvent stopEvent;
public IOptimizer Optimizer { get; private set; }
private static PLMOptimizationLoop instance;
//Singleton Pattern Used
public static PLMOptimizationLoop Instance
{
get { return (instance ?? (instance = new PLMOptimizationLoop())); }
}
protected override void Dispose(bool disposing)
{
SafeDispose(ref stopEvent);
base.Dispose(disposing);
}
private void OptimizationThread()
{
if (Optimizer == null)
throw new NullReferenceException("Optimizer");
Optimizer.Initialize();
while (true)
{
// if stopped externally
if (this.stopEvent.WaitOne(1000))
break;
// execute optimizer, continue to call execute only if the optimizer requires it
if (this.Optimizer.Execute())
continue;
// set thread to null only if exiting on its own
// in case stop was called the caller will wait for this thread to exit
// and then make the thread object null
this.PLMOptimizerThread = null;
break;
}
Optimizer.Shutdown();
}
private PLMOptimizationLoop()
{
this.stopEvent = new AutoResetEvent(false);
this.PLMOptimizerThread = null;
}
int a = 0;
public void Start(IOptimizer optimizer)
{
a = 1;
if (optimizer == null)
throw new ArgumentNullException("optimizer");
this.Optimizer = optimizer;
this.PLMOptimizerThread = new Thread(OptimizationThread);
this.PLMOptimizerThread.Start();
}
public void Stop()
{
if (this.PLMOptimizerThread == null)
return;
this.stopEvent.Set();
this.PLMOptimizerThread.Join();// **********the problem seems to be here ****//
this.PLMOptimizerThread = null;
}
}
}
以上代码试图运行我的算法:
namespace ILS.PLMOptimization.Algorithm
{
public class PLMOptimizationAlgorithm : IOptimizer
{
public void Initialize()
{
//somecode here
}
public bool Execute()
{
//somecode here
}
public void Shutdown()
{
//somecode here
}
public int ResetLuminaire_To_DefaultStateonSTop()
{
//somecode here
}
public PLMOptimizationAlgorithm()
{
//somecode here
}
}
}
答案 0 :(得分:0)
如果“Execute”方法需要很长时间,则线程将不会在join-Method中接收stop事件和GUI线程块。如果通过stopEvent发出Cancelation请求信号,则必须更频繁地评估此事件,这也意味着在长时间运行的Execute-Method中。 对于此目的,CancellationToken(https://msdn.microsoft.com/de-de/library/dd997364%28v=vs.110%29.aspx)有时更有用,您必须将它传递给每个长时间运行的函数,在本例中为Execute。许多人通过此令牌构建功能支持取消。
如果您想在Optimizer线程中更新WPF-GUI,请使用Dispatcher将请求传递给GUI-Thread:Using the C# Dispatcher