• Winform软件,不要在线程里操作UI


    对于Winform软件,不要在线程里操作UI,不要相信:StartForm.CheckForIllegalCrossThreadCalls = false;

    于是,把所有的代码都改成主线程委托调用的方式

    private delegate void SetTextHandle(string id, string value);
    
            private void ThreadSetText(string id, string value)
            {
                this.Controls.Find(id, true)[0].Text = value;
            }
            private void SetText(string id, string value)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new SetTextHandle(ThreadSetText), new object[] { id, value });
                }
                else
                {
                    ThreadSetText(id, value);
                }
            }
    

    2

    // the canonical form (C# consumer)
    
    public delegate void ControlStringConsumer(Control control, string text);  // defines a delegate type
    
    public void SetText(Control control, string text) {
        if (control.InvokeRequired) {
            control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text});  // invoking itself
        } else {
            control.Text=text;      // the "functional part", executing only on the main thread
        }
    }
    

     3

    public static class ControlHelpers
    {
        public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : ISynchronizeInvoke
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new Action(() => action(control)), null);
            }
            else
            {
                action(control);
            }
        }
    }
    

    Use it like this:

    private void UpdateSummary(string text)
    {
        summary.InvokeIfRequired(s => { s.Text = text });
    }

    3
    theLabel.Invoke(new Action(() => theLabel.Text = "hello world from worker thread!"));
    

     4

    public static void InvokeIfRequired(this Control control, MethodInvoker action)
    {
        if (control.InvokeRequired) {
            control.Invoke(action);
        } else {
            action();
        }
    }
    

     调用:

    richEditControl1.InvokeIfRequired(() =>
    {
        // Do anything you want with the control here
        richEditControl1.RtfText = value;
        RtfHelpers.AddMissingStyles(richEditControl1);
    });
    

     更新为:

    public static void InvokeIfRequired(this ISynchronizeInvoke obj,
                                             MethodInvoker action)
    {
        if (obj.InvokeRequired) {
            var args = new object[0];
            obj.Invoke(action, args);
        } else {
            action();
        }
    }
    

     考虑仍出现异常时:

    while (!control.Visible)
    {
        System.Threading.Thread.Sleep(50);
    }


    5
    public static void InvokeIfRequired(this Control c, Action<Control> action)
    {
        if(c.InvokeRequired)
        {
            c.Invoke(new Action(() => action(c)));
        }
        else
        {
            action(c);
        }
    }
    

     变更为:

    public static void InvokeIfRequired<T>(this T c, Action<T> action) 
        where T : Control
    

     调用方法:

    object1.InvokeIfRequired(c => { c.Visible = true; });
    
  • 相关阅读:
    造数据
    自定义注解
    利用线程池,同步线程实现并发
    ThreadPoolExecutor 线程池
    velocity 模板
    [python] 解析xml文件
    url 中需要转义的字符
    Appium 坑
    TestNG 101
    【python】print · sys.stdout · sys.stderr
  • 原文地址:https://www.cnblogs.com/zeroone/p/6059838.html
Copyright © 2020-2023  润新知