`
hzy3774
  • 浏览: 992396 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

C#解决跨线程调用错误的简单方法

 
阅读更多

窗体程序中我们常把费时操作另开新线程,但是我们要知道新线程的运行状态,又要对UI线程进行操作来显示新线程状态;例如:

namespace CrossCall
{
    public partial class Form1 : Form
    {
        Thread thread = null;

        public Form1()
        {
            InitializeComponent();
            //CheckForIllegalCrossThreadCalls = false;
            thread = new Thread(fun);
            thread.Start();//启用新线程
        }

        private void fun()
        {
            int i = 10;
            while (i-- > 0)
            {
                label1.Text = i.ToString();//在新线程中更新UI控件
                Thread.Sleep(1000);
            }
        }

        //如果程序关闭后线程还在运行,则关闭线程
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (thread != null)
            {
                thread.Abort();
            }
        }
    }
}

 

 

 这时程序运行就发生错误了:



 这种错误我一般用以下两种方法解决:

1.对于那种明知道跨线程调用不会带来错误的,可以设置Form控件不检查跨线程调用错误,这样就不报错了。

在Form1构造方法中:

CheckForIllegalCrossThreadCalls = false;

 2.但是,为了防止多个线程同时更新控件造成错误,也可以采用代理的方法:

Control .BeginInvoke 方法 (Delegate)在创建控件的基础句柄所在线程上异步执行指定委托。

这是帮助文档的例子:

public delegate void InvokeDelegate();

private void Invoke_Click(object sender, EventArgs e)
{
   myTextBox.BeginInvoke(new InvokeDelegate(InvokeMethod));
}
public void InvokeMethod()
{
   myTextBox.Text = "Executed the given delegate";
}

 如果我们不像自己去写委托,可以使用MethodInvoker 委托:

MethodInvoker 提供一个简单委托,该委托用于调用含 void 参数列表的方法。 在对控件的 Invoke 方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。

所以,代码可改写为:

 

namespace CrossCall
{
    public partial class Form1 : Form
    {
        Thread thread = null;

        public Form1()
        {
            InitializeComponent();
            //CheckForIllegalCrossThreadCalls = false;
            thread = new Thread(fun);
            thread.Start();//启用新线程
        }

        private void fun()
        {
            int i = 10;
            while (i-- > 0)
            {
                //label1.Text = i.ToString();//在新线程中更新UI控件
                BeginInvoke(new MethodInvoker(delegate()
                {
                    label1.Text = i.ToString();//在新线程中更新UI控件
                }));
                Thread.Sleep(1000);
            }
        }

        //如果程序关闭后线程还在运行,则关闭线程
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (thread != null)
            {
                thread.Abort();
            }
        }
    }
}

 

 控件和Form都有BeginInvoke方法,要注意BeginInvoke必须要在控件创建之后才能调用。



程序正常执行。 

核心代码:

CheckForIllegalCrossThreadCalls = false;

BeginInvoke(new MethodInvoker(delegate()
{
 })); 

 

 

  • 大小: 39.7 KB
  • 大小: 9.6 KB
分享到:
评论

相关推荐

    C# 跨线程调用控件

    为了解决这个问题,我们需要采用一种标准的跨线程调用控件的方法。 一、理解线程安全与UI线程 1. **线程安全**:线程安全是指在多线程环境下,一个类或方法能够正确地处理并发访问,不会导致数据混乱或异常。在...

    c#跨线程间控件调用

    除了 `InvokeRequired` 属性之外,`Invoke` 方法也是解决跨线程调用控件的关键之一。该方法允许从非创建控件的线程安全地调用该控件的方法。通常情况下,会结合 `Delegate`(委托)使用 `Invoke` 方法,以确保代码的...

    C#WinForm跨线程安全调用控件例程

    在跨线程调用中,委托扮演了关键角色,因为它允许我们在一个线程中定义一个方法,然后在另一个线程中安全地执行这个方法。 **2. 跨线程调用控件:** 当需要在后台线程中更新UI时,我们不能直接调用控件的方法,而...

    C#WinForm跨线程更新UI的四种方法

    以上四种方法都可以有效地解决WinForms应用中跨线程更新UI的问题,选择哪种方法主要取决于具体需求,如是否需要等待后台操作完成、是否希望简化编程模型等。在实际开发中,通常推荐使用BackgroundWorker,因为它提供...

    C# 跨线程访问UI线程控件

    在C#中,由于使用线程和调用UI的线程属于两个不同的线程,如果在线程中直接设置UI元素的属性,此时就会出现跨线程错误。    下面介绍两种解决方案  第一种:使用控件自带的Invoke或者BeginInvoke方法。 Task....

    跨线程进行Windows窗体控件的访问

    标题提到的“跨线程进行Windows窗体控件的访问”是一个重要的主题,因为错误的线程交互可能引起程序崩溃或者难以调试的错误。 当一个控件由一个线程创建后,原则上只能由该线程修改。如果其他线程尝试修改同一控件...

    跨线程访问Windows窗体控件

    3. 使用`Control.CheckForIllegalCrossThreadCalls`属性:虽然不推荐,但你可以临时禁用这个检查以允许跨线程访问,但这可能导致难以调试的错误,所以仅限于调试阶段。 ```csharp Control....

    跨线程访问控件实例.rar

    总结来说,“跨线程访问控件实例”着重于在多线程环境中解决UI控件的更新问题,避免线程冲突和错误。通过学习和理解这个实例,开发者可以更好地掌握线程同步和UI更新的最佳实践,提升应用程序的稳定性和性能。对于...

    c#在多线程中访问Form中控件的多种解决方案

    一种简单的方法是在应用程序中禁用跨线程访问检查: ```csharp Control.CheckForIllegalCrossThreadCalls = false; ``` **优点:** - 实现简单,易于理解。 - 可以快速解决问题。 **缺点:** - 这种做法可能导致...

    c# 多线程任务中结束全部线程

    在给定的代码片段中,虽然存在一些乱码字符,但我们可以从中抽取出与多线程相关的知识点,包括如何创建线程、使用委托进行跨线程调用以及如何优雅地关闭线程。 ### 创建线程 在C#中,`System.Threading.Thread`类...

    C#跨应用程序调用。项目可以启动其他程序获取输出

    在C#编程中,跨应用程序调用是一种常见的需求,它允许一个程序启动、控制或通信与其他已安装在系统上的程序。这种技术对于实现系统集成、自动化任务或是扩展应用程序功能非常有用。本文将深入探讨如何使用C#进行跨...

    C#中跨线程访问控件问题解决方案[文].pdf

    在C#编程中,当你在多线程环境中尝试直接访问由主线程创建的UI控件时,会遇到“跨线程访问控件”的问题。这是因为Windows Forms和WPF框架为了保证用户界面(UI)线程的安全性和一致性,不允许非创建线程修改UI组件。...

    c# window服务多线程实例

    在上述代码中,`OnStart()`方法创建了一个新线程并调用`DoWork()`方法。`DoWork()`方法包含了服务的主要工作流程,其中使用`Thread.Sleep()`模拟了耗时操作。当服务停止时,`OnStop()`方法会被调用,你可以在这里...

    C#跨线程访问控件的实例

    然而,由于Windows Forms或WPF等GUI框架的线程安全特性,直接在非UI线程(后台线程)中修改UI控件的状态(如文本、颜色等)会导致“Cross-threading”错误,即跨线程访问异常。本文将深入探讨如何在C#中正确处理跨...

    C#多线程与跨线程访问界面控件的方法

    在C#编程中,多线程技术被广泛用于提高应用程序的执行效率,特别是在处理耗时操作如网络请求、...在实际开发中,还需要根据具体需求选择合适的方法来解决跨线程访问UI的问题,同时要考虑性能、可维护性和线程安全。

    Invoke跨线程调用的代码

    忽略跨线程访问的错误 CheckForIllegalCrossThreadCalls = false,但是这个方法很不稳定,使用invoke方法解决跨线程访问的问题,里边有2个例子, 通过自己额外创建的线程改变label控件中的内容从而验证invoke方法

    基于C#的socket实例

    在这个项目中,我们将深入探讨Socket的基本概念、C#中的Socket类、跨线程通信以及委托回调机制。 Socket,也被称为套接字,是网络编程的基础,它提供了一种在不同计算机之间建立连接并进行数据交换的接口。在C#中,...

    C# winform多线程模板示例,winform多线程例子,C#

    - **UI更新**:由于跨线程更新UI不安全,需使用控件的`Invoke`或`BeginInvoke`方法确保在主线程上进行更新。 - **进度条显示**:通过`ProgressChanged`事件报告进度,更新UI上的进度条。 - **任务完成通知**:在`...

    vbnet线程入门详解_跨线程调用窗体控件[收集].pdf

    【VB.NET线程入门详解与跨线程调用窗体控件】 VB.NET中的线程是程序执行的核心组件,它们代表了程序中的独立控制流。理解并熟练掌握线程的使用对于提高应用程序的效率和用户体验至关重要。在VB.NET中,线程允许我们...

Global site tag (gtag.js) - Google Analytics