Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 避免跨线程操作错误的最简洁、最恰当的方法?_C#_Multithreading - Fatal编程技术网

C# 避免跨线程操作错误的最简洁、最恰当的方法?

C# 避免跨线程操作错误的最简洁、最恰当的方法?,c#,multithreading,C#,Multithreading,我不太擅长代表,我不明白在幕后发生了什么。当从不同线程访问UI项时,我得到了跨线程操作错误 我想做的是在实用工具类中编写一个泛型函数,这样我就可以将任何方法/代码块传递给函数。我可以用很多方法来做,比如: 我相信方法1和2基本上是相同的,4、5和6也是一样的。我的问题是: 方法(1和2)、3和(4、5和6)之间有什么区别?我的意思是,在什么情况下,一方处理/照顾另一方不处理/照顾 避免跨线程操作错误的正确方法是什么?从这个意义上讲,它可以处理所有情况,最好简洁易读 上述“第三种”方法

我不太擅长代表,我不明白在幕后发生了什么。当从不同线程访问UI项时,我得到了
跨线程操作
错误

我想做的是在
实用工具
类中编写一个泛型函数,这样我就可以将任何方法/代码块传递给函数。我可以用很多方法来做,比如:

  • 我相信方法1和2基本上是相同的,4、5和6也是一样的。我的问题是:

  • 方法(1和2)、3和(4、5和6)之间有什么区别?我的意思是,在什么情况下,一方处理/照顾另一方不处理/照顾

  • 避免
    跨线程操作
    错误的正确方法是什么?从这个意义上讲,它可以处理所有情况,最好简洁易读

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

    第三个选项直接使用传入的
    操作
    ,这更简单

    第一个选项与此类似,不过在这种情况下,您将传入不必要的值(控件
    和必须定义自定义委托的值)(尽管您可以使用
    操作
    )。由于没有使用控件,因此没有理由增加这种复杂性

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

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

    如果你不打算登录,只打算重新浏览,你可以完全省去
    try
    /
    catch

    我对
    MethodInvoker
    更感到困惑。。它在替代
    委托
    操作
    ()=>
    关键字方面做了什么特别的事情?@nawfal这只是另一个委托声明。实际上,这与使用
    操作
    相同。
    =>
    语法是一个lambda表达式,它是用于生成匿名方法的较新语法(类似于
    委托{}
    ,但具有更清晰的语法)。
    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;
        }
    }
    
    catch (Exception ex)
    {
        // Do whatever, ie: logging
        throw;
    }