編輯: 請參閱問題歷史記錄,對於未更改的問題以便使註釋無效。當從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你可能是對的,但是每個方法都可以在其他地方調用,我從一個方法調用每個方法,你認爲哪個片斷可能會丟失? –