问题
private delegate void Runner(); //A delegate, but this attempt didn't work
public void Run()
{
Stager.InstructionsMemory = InstructionsTextBox.Text.Split('\n');
Stager.InintializeLists();
InstructionThread = new Thread[Stager.InstructionsMemory.Length];
PipelineInitializor();
BlockingCollection<Func<object>>[] tasks = new BlockingCollection<Func<object>>[Stager.InstructionsMemory.Length];
PCounterLabelUpdate up = new PCounterLabelUpdate(PCounterLabelUpdater);
MemoryUpdater MemUp = new MemoryUpdater(UpdateMemoryLists);
ButtonControl del = new ButtonControl(ButtonController);
ExecuteBtn.Invoke(del, new bool[] { false, true });
Cycle = 0;
for (APCounter = 0; APCounter < Stager.InstructionsMemory.Length; APCounter++)
{
int i1 = APCounter;
int i = APCounter; //Local Copy of Counter
tasks[i] = new BlockingCollection<Func<object>>();
tasks[i].Add(() => Fetch(i1));
tasks[i].Add(() => Decode(i1));
tasks[i].Add(() => ALURes(i1));
tasks[i].Add(() => Memory(i1));
tasks[i].Add(() => WriteB(i1));
InstructionThread[i] = new Thread(() => Worker(i1, tasks[i1]));
InstructionThread[i1].Start(); //Start a Thread
CycleLbl.Invoke(up); // Update GUI Control
this.Invoke(MemUp); // UPdate GUI
_wait.WaitOne(); //Wait
}
ExecuteBtn.Invoke(del, new bool[] { true, false });
}
The GUI totally freezes disallowing me of calling the set method.
The above functions is a threads launcher, I want to lunch a certain amount of threads, but I want delay the lunch based on an condition. I use for loop, and _wait.WaitOne();
What Calls Run? A button control
What line does it get stuck on? _wait.WaitOne()
What Wait Is? AutoResetEvent
Why is it after the lunch of the first thread? I want to control the groups of starting threads, let them get the job done ("Using Business Logic") , then lunch more threads.
回答1:
You are calling AutoResetEvent.WaitOne on the UI thread. WaitOne does not pump messages so it will cause the UI to freeze. The general advice here to avoid calling any kind of method that blocks the UI thread while it is waiting for a signal from another thread. This prevents the UI thread from dispatching all of the events that occurring (like button clicks, refreshing the screen, etc.). Worse still, if used incorrectly it can cause deadlocks which may be what is happening in your case. Without seeing how that AutoResetEvent is Set I cannot say for sure what the problem is, but calling WaitOne on the UI thread is definitely a problem.
By the way, you are also calling Control.Invoke on the UI thread which is a bit odd. This leads me to believe that there is a lot more going than what you have presented in your question or you have a fundamental misunderstanding of how Invoke is suppose to be used.
来源:https://stackoverflow.com/questions/10423966/threads-totally-freezes-the-gui