首页 > 解决方案 > Invoke 和 BeginInvoke 不会运行真正的异步

问题描述

好的,有一些解决方案可以修复多线程 Windows 窗体。我的就是这样......只有1秒的延迟:

private delegate void StupidDumb();
private void StupidFreakingDumb()
{
    RespondLbl.BeginInvoke(new StupidDumb(() => RespondLbl.Text = "Responding: Loading..."));
    // Then refresh
    new Thread(() =>
    {
        RespondLbl.BeginInvoke(new StupidDumb(() => RespondLbl.Text = $"Responding: {SerialCommunication.Responding}"));
        // The 'SerialCommunication.Responding' property takes up to one second to retrieve information, which is the same amount of time the form is not responding.
    }).Start();
}
private void RefreshBtn_Click(object sender, EventArgs e)
{
    BeginInvoke(new Action(StupidFreakingDumb));
}

我把它放在代码中,但我也会把它放在这里:

“'SerialCommunication.Responding' 属性最多需要一秒钟来检索信息,这与表单没有响应的时间相同。”

在“RefreshBtn_Click”方法中,我尝试了 BeginInvoke、Invoke 和新的 Thread 实例。

我得到的最接近的是新的 Thread 方法,并且确实更新了显示“响应:正在加载...”的表单,但随后冻结了整整 1 秒,直到 SerialCommunication.Responding 返回一个值。

编辑(我有发布一些东西然后很快找到解决方案的坏习惯):

改变了

RespondLbl.BeginInvoke(new StupidDumb(() => RespondLbl.Text = $"Responding: {SerialCommunication.Responding}"));

string poop = SerialCommunication.Responding.ToString();
RespondLbl.BeginInvoke(new StupidDumb(() => RespondLbl.Text = $"Responding: {poop}"));

那解决了它。只需确保长过程(例如,SerialCommunication.Responding)不是 Invoke/BeginInvoke 方法的一部分。然后把它放在一个单独的对象中,一旦该对象具有该值,触发 Invoke/BeginInvoke (微小的差异,都尝试过,甚至无法分辨)

标签: c#.netasynchronous

解决方案


我把答案放在这里:

我变了

RespondLbl.BeginInvoke(new StupidDumb(() => RespondLbl.Text = $"Responding: {SerialCommunication.Responding}"));

string poop = SerialCommunication.Responding.ToString();
RespondLbl.BeginInvoke(new StupidDumb(() => RespondLbl.Text = $"Responding: {poop}"));

只要确保长过程(在我的例子中是 SerialCommunication.Responding)不是 Invoke/BeginInvoke 方法的一部分。然后将其分配给一个单独的对象,一旦该对象具有该值,触发 Invoke/BeginInvoke (细微的差异,都尝试过,甚至无法分辨)


推荐阅读