编辑: 请参阅问题历史记录,对于未更改的问题以便使注释无效。当从UI调用到System.Threading.Thread时,挂起挂起挂起
我点击执行某些代码的按钮,它创建一个线程(System.Threading.Thread)。当我重新点击启动进程的按钮时,它会挂起并冻结ui。可能是什么原因?
public partial class ucLoader : UserControl
{
//lock object for whole instance of class ucLoader
private object lockUcLoader = new object();
//bringing info from ui
private void btnBringInfo_Click(object sender, EventArgs e)
{
lock (lockUcLoader)
{
btnBringInfo_PerformClick(false);
}
}
//using this method because it could be called when even button not visible
internal void btnBringInfo_PerformClick(bool calledFromBandInit)
{
lock (lockUcLoader) //HANGS HERE when called multiple times and ui freeze as well
//by the way I am using (repetitive) lock, because this method also called independently from btnBringInfo_Click
{
//...
this.btnLoad_PerformClick();
}
}
//Another button perform click that could be triggered elsewhere when even button not visible
private void btnLoad_PerformClick()
{
lock (lockUcLoader) //I am using (repetitive) lock, because this method also called independently from btnBringInfo_PerformClick
{
//...
Run();
}
}
//method for creating thread which System.Threading.Thread
private void Run()
{
lock (lockUcLoader) //Maybe this lock is NOT REQUIRED, as it is called by only btnLoad_PerformClick(), could you please confirm?
{
//some code that thread can be killed when available, you can ingore this two lines as they are irrelevant to subject, I think
Source = new CancellationTokenSource();
Token = Source.Token;
var shell = new WindowsShell();
Thread = new Thread((object o) =>
{
//...
var tokenInThread = (CancellationToken)o;
exitCode =TaskExtractBatchFiles(cls, shell, exitCode);
using (var logEnt = new logEntities())
{
//Do some db operation
//...
this.Invoke((MethodInvoker)delegate
{
//do some ui update operation
//...
});
}
}
Thread.Start(Token);
}
}
public void Progress(string message)
{
Invoke((MethodInvoker)delegate //ATTENTION HERE see below picture Wait occurs here
{
if (message != null && message.Trim() != string.Empty)
{
this.txtStatus.AppendText(message + Environment.NewLine);
}
});
}
}
为了避免获得封闭的问题,我的问题是什么,我怎么能防止 以下方法可以访问与后台线程进行锁定和UI线程
public void Progress(string message)
{
Invoke((MethodInvoker)delegate //ATTENTION HERE see below picture Wait occurs here
{
if (message != null && message.Trim() != string.Empty)
{
this.txtStatus.AppendText(message + Environment.NewLine);
}
});
}
您的主线程必须阻止某处,所以锁定没有被释放。找出那里。顺便说一句:你真的*开始*线程? – Fildor
锁太多。这可能表明缺乏知识,但它[很容易解决](http://www.albahari.com/threading/)。您没有显示足够的代码: 谁调用了'TaskExtractBachFiles'? – Sinatr
@Sinatr你可能是对的,但是每个方法都可以在其他地方调用,我从一个方法调用每个方法,你认为哪个片断可能会丢失? –