c# - 避免跨线程操作错误的最简洁和正确的方法?

标签 c# multithreading

我不太擅长代表,我不明白幕后发生的事情。我得到 cross thread operation从不同线程访问 UI 项时出错。

我想做的是在 Utility 中编写一个通用函数类,以便我可以将任何方法/代码块传递给函数。我可以通过多种方式做到这一点,例如:

  • delegate void UpdateGui(Control c, Action action);
    public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired)
            {
                UpdateGui updaterdelegate = new UpdateGui(Do);
                c.TopLevelControl.Invoke(updaterdelegate, new object[] { c, action });
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  • public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke((Action)delegate { Do(c, action); });
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  • public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired)
            {
                c.TopLevelControl.Invoke(action);
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  • public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke(new MethodInvoker(() => action()));
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  • public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke(new MethodInvoker(delegate { action(); }));
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  • public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke((MethodInvoker)delegate { action(); });
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    

  • 我相信方法 1 和 2 基本相同,方法 4、5 和 6 也是如此。我的问题是:
  • 方法 (1 & 2)、3 和 (4, 5 & 6) 之间有什么区别?我的意思是在什么情况下一个人处理/照顾另一个人不处理?
  • 避免cross thread operation的正确方法是什么?错误,从某种意义上说它处理所有情况,最好是简洁易读?
  • 最佳答案

    您上面的“第三种”方法(仅使用 Action )更简单、更有效。您使用 delegate 的其他方法创建一个单独的方法(通过 delegate 关键字的匿名方法)然后调用您的原始委托(delegate)(action 参数),这是不必要的。

    第三个选项直接使用 Action传入,比较简单。

    第一个选项是类似的,但在这种情况下,您传递了不必要的值( Control )以及必须定义自定义委托(delegate)(尽管您可以使用 Action<Control,Action> 代替)。由于没有使用控件,因此没有理由增加这种复杂性。

    附带说明 - 当您在异常处理程序中重新抛出时,最好只使用 throw; (而不是 throw ex; ),因为这将正确保留堆栈跟踪:

    catch (Exception ex)
    {
        // Do whatever, ie: logging
        throw;
    }
    

    如果你不打算登录,只是打算重新抛出,你可以省略 try/catch完全。

    关于c# - 避免跨线程操作错误的最简洁和正确的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12901938/

    相关文章:

    c# - 我们什么时候必须在 C# 中使用 checked 运算符?

    c# - 通过检查器选择要引用的列表

    c++ - OpenMP:循环遍历 'std::map' 基准(动态调度)

    iphone - 应该如何使用dispatch_debug?

    c# - 用数据库中的数据填充文本框

    c# - SCOPE_INDENTITY() 不工作它返回 null 吗?

    c# - 根据角色限制用户可以做什么

    java - 当另一个对象中的线程触发事件时,Swing 接口(interface)不更新组件

    java - 尽管被要求通过中断终止,计时器线程仍会徘徊

    java - 可调用任务未正确执行