【问题标题】:Threads totally freezes the GUI线程完全冻结了 GUI
【发布时间】:2012-05-12 12:43:54
【问题描述】:
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 });
}

GUI 完全冻结,不允许我调用 set 方法。

以上函数是线程启动器,我想午餐一定数量的线程,但我想根据条件延迟午餐。我使用 for 循环和 _wait.WaitOne();

什么叫运行?一个按钮控件

卡在哪条线上? _wait.WaitOne()

什么是等待?自动重置事件

为什么是在第一个线程的午餐之后?我想控制启动线程组,让他们完成工作(“使用业务逻辑”),然后午餐更多线程。

【问题讨论】:

  • 什么调用 Run()?当它被调用时,它卡在哪条线上?如果该行是'_wait.WaitOne()',什么是'_wait',(可能是阻塞同步类型)?为什么第一个线程启动后它在循环内?
  • @MartinJames 请再次检查

标签: c# multithreading user-interface delegates invoke


【解决方案1】:

您正在 UI 线程上调用 AutoResetEvent.WaitOneWaitOne 不会发送消息,因此会导致 UI 冻结。这里的一般建议是避免在 UI 线程等待来自另一个线程的信号时调用任何阻塞 UI 线程的方法。这可以防止 UI 线程调度所有发生的事件(如按钮单击、刷新屏幕等)。更糟糕的是,如果使用不当,可能会导致死锁,这可能是您的情况。在没有看到AutoResetEventSet 的情况下,我无法确定问题是什么,但在UI 线程上调用WaitOne 绝对是个问题。

顺便说一句,您还在 UI 线程上调用 Control.Invoke,这有点奇怪。这使我相信,除了您在问题中提出的内容之外,还有很多事情要做,或者您对 Invoke 的使用方式存在根本性的误解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多