如何从另一个线程更新 GUI 上的文本框[重复]

2023-11-25

我是 C# 新手,我正在尝试制作一个简单的客户端服务器聊天应用程序。

我的客户端窗口窗体上有 RichTextBox,我正在尝试从另一个类中的服务器更新该控件。当我尝试这样做时,我收到错误:“跨线程操作无效:控制 textBox1 从创建它的线程以外的线程访问”。

这是我的 Windows 窗体的代码:

private Topic topic;  
public RichTextBox textbox1;  
bool check = topic.addUser(textBoxNickname.Text, ref textbox1, ref listitems);

主题类:

public class Topic : MarshalByRefObject  
{  
    //Some code
 public  bool addUser(string user, ref RichTextBox textBox1, ref List<string> listBox1)  
 {  
     //here i am trying to update that control and where i get that exception  
     textBox1.Text += "Connected to server... \n";  
}

那么如何做到这一点呢?如何从另一个线程更新文本框控件?


我正在尝试使用 .net 远程处理制作一些基本的聊天客户端/服务器应用程序。 我想将 Windows 窗体客户端应用程序和控制台服务器应用程序作为单独的 .exe 文件。在这里,我尝试从客户端调用服务器函数 AddUser,并且我想要 AddUser 函数更新我的 GUI。我已经按照乔恩的建议修改了代码,但现在我得到了这个异常,而不是跨线程异常......“SerializationException:程序集中的类型主题未标记为可序列化”.

我将在下面发布我的整个代码,并尝试使其尽可能简单。
欢迎任何建议。非常感谢。

Server:

  namespace Test
{
    [Serializable]
    public class Topic : MarshalByRefObject
    {
        public bool AddUser(string user, RichTextBox textBox1, List<string> listBox1)
        {
            //Send to message only to the client connected
            MethodInvoker action = delegate { textBox1.Text += "Connected to server... \n"; };
            textBox1.BeginInvoke(action);
            //...
            return true;
        }

        public class TheServer
        {
            public static void Main()
            {

                int listeningChannel = 1099;

                BinaryServerFormatterSinkProvider srvFormatter = new BinaryServerFormatterSinkProvider();
                srvFormatter.TypeFilterLevel = TypeFilterLevel.Full;

                BinaryClientFormatterSinkProvider clntFormatter = new BinaryClientFormatterSinkProvider();

                IDictionary props = new Hashtable();
                props["port"] = listeningChannel;

                HttpChannel channel = new HttpChannel(props, clntFormatter, srvFormatter);
                // Register the channel with the runtime            
                ChannelServices.RegisterChannel(channel, false);
                // Expose the Calculator Object from this Server
                RemotingConfiguration.RegisterWellKnownServiceType(typeof(Topic),
                                                    "Topic.soap",
                                                    WellKnownObjectMode.Singleton);
                // Keep the Server running until the user presses enter
                Console.WriteLine("The Topic Server is up and running on port {0}", listeningChannel);
                Console.WriteLine("Press enter to stop the server...");
                Console.ReadLine();
            }
        }
    }

}  

Windows 窗体客户端:

// Create and register a channel to communicate to the server
        // The Client will use the port passed in as args to listen for callbacks

        BinaryServerFormatterSinkProvider srvFormatter = new BinaryServerFormatterSinkProvider();
        srvFormatter.TypeFilterLevel = TypeFilterLevel.Full;
        BinaryClientFormatterSinkProvider clntFormatter = new BinaryClientFormatterSinkProvider();
        IDictionary props = new Hashtable();
        props["port"] = 0;

        channel = new HttpChannel(props, clntFormatter, srvFormatter);
        //channel = new HttpChannel(listeningChannel);

        ChannelServices.RegisterChannel(channel, false);
        // Create an instance on the remote server and call a method remotely
        topic = (Topic)Activator.GetObject(typeof(Topic), // type to create
        "http://localhost:1099/Topic.soap" // URI
        );


        private Topic topic;
        public RichTextBox textbox1;
        bool check = topic.addUser(textBoxNickname.Text,textBox1, listitems);

你需要使用BackgroundWorker, or Control.Invoke/BeginInvoke。匿名函数 - 匿名方法 (C# 2.0) 或 lambda 表达式 (C# 3.0) 使这比以前更容易。

对于您的情况,您可以将代码更改为:

public bool AddUser(string user, RichTextBox textBox1, List listBox1)
{
    MethodInvoker action = delegate
         { textBox1.Text += "Connected to server... \n"; };
    textBox1.BeginInvoke(action);
}

有几点需要注意:

  • 为了符合 .NET 约定,这应该被称为AddUser
  • 您不需要通过引用传递文本框或列表框。我怀疑你不太明白什么ref真正的意思是——看我关于参数传递的文章更多细节。
  • 和...之间的不同Invoke and BeginInvoke就是它BeginInvoke在继续之前不会等待 UI 线程上调用委托 - 所以AddUser可能会在文本框之前返回actually已更新。如果您不想要这种异步行为,请使用Invoke.
  • 在许多示例(包括我的一些示例!)中,您会发现人们使用Control.InvokeRequired看看他们是否需要打电话Invoke/BeginInvoke。在大多数情况下,这实际上是多余的——没有真正的harm在呼唤中Invoke/BeginInvoke即使您不需要,并且处理程序通常会only无论如何,永远不会从非 UI 线程调用。省略检查使代码更简单。
  • 您还可以使用BackgroundWorker正如我之前提到的;这特别适合进度条等,但在这种情况下,保留当前模型可能同样容易。

有关此主题和其他线程主题的更多信息,请参阅我的线程教程 or 乔·阿尔巴哈里的一个.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从另一个线程更新 GUI 上的文本框[重复] 的相关文章

  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 用于运行可执行文件的python多线程进程

    我正在尝试将一个在 Windows 上运行可执行文件并管理文本输出文件的 python 脚本升级到使用多线程进程的版本 以便我可以利用多个核心 我有四个独立版本的可执行文件 每个线程都知道要访问它们 这部分工作正常 我遇到问题的地方是当它们
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • GUI Java 程序 - 绘图程序

    我一直试图找出我的代码有什么问题 这个想法是创建一个小的 Paint 程序并具有红色 绿色 蓝色和透明按钮 我拥有我能想到的让它工作的一切 但无法弄清楚代码有什么问题 该程序打开 然后立即关闭 import java awt import
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 单击时如何不突出显示 NSButton 的模板图像?

    我在 NSTableView 的每一行都有 NSButtons 按钮图像在 IB 中设置 并且带 Alpha 通道的黑色图标 窗口设置为暗模式 window appearance NSAppearance named NSAppearanc
  • 如何在 Twitter Rest API v1.1 中从 FHSTwitterEngine 完全注销?

    FHSTwitterEngine engine FHSTwitterEngine sharedEngine engine clearAccessToken 我尝试了上面的代码 但是当我尝试再次登录时 文本字段不会出现在presentModa
  • 是否有 Perl 模块或技术可以更轻松地使用长命名空间?

    有些命名空间又长又烦人 假设我下载了名为 FooFoo BarBar BazBaz tar gz 的假设包 它具有以下模块 FooFoo BarBar BazBaz Bill FooFoo BarBar BazBaz Bob FooFoo
  • 为什么即使不调用公共复制构造函数也需要它?

    拥有一个公共复制构造函数将使小程序 编译 但不显示副作用 复制 include
  • 水平线上的三角形指针/边框

    我正在尝试在水平线上创建三角形指针 边框 这是我想要实现的目标的示例 我尝试操纵 div 的顶部边框 但到目前为止我所做的一切根本不起作用 有多种方法可以实现这一点 这可能取决于您的布局 一种解决方案是使用两侧带有边框的旋转元素 trian
  • PublicKeyCredential 无法序列化

    我正在 Angular 应用程序中实现 FIDO2 WebAuthn 我已经获得了 PublicKeyCredentialCreationOptions 对象和 seccessfullt 寄存器 但打电话后 let response awa
  • VB.Net - Excel COM 对象未释放[重复]

    这个问题在这里已经有答案了 我面临的问题是 即使在调用 ReleaseComObject 和 GC Collect 方法后 Excel Process 仍保持活动状态 我的 Excel 进程终止 但仅在我关闭用户表单后才终止 下面是示例代码
  • Kafka JDBC Sink 连接器:未分配任务

    我尝试使用以下配置启动 JDBC 接收器连接器 name crm data sink hh config connector class io confluent connect jdbc JdbcSinkConnector tasks m
  • 如何在没有消息泵送的情况下等待 WaitHandle?

    我想打电话WaitHandle WaitOne TimeSpan 在 NET中 但我在STA线程上 它在等待时泵送消息 由于超出了这个问题范围的原因 我需要等待without泵送 如何在不发送消息的情况下等待 WaitHandle 发出信号
  • ng-bind-html 给出无限摘要错误 ($rootScope.infdig)

    如果我使用常规函数ng bind 一切似乎都很好 但如果我要使用ng bind html 我收到无限摘要错误 View 1 span 2 span Controller 1 scope test function return 1 2 my
  • Spring调度任务-只运行一次

    是否可以在指定的时间只安排一次 Spring 服务方法 例如 当前时间是下午 2 点 但当我点击操作按钮时 我希望我的服务方法在晚上 8 点开始 我熟悉 Scheduled 注释 但不知道如何编写 cron 表达式而不定期运行 这个 Sch
  • 向 TinyMCE 字体选项添加新字体

    我已经检查过这个线程 谷歌字体和 TinyMCE事实上 之前甚至已经成功地将新字体添加到用户的 TinyMCE 字体选项中 但我不确定这里出了什么问题以及为什么我不能再这样做了 我正在尝试添加新字体 Samman 这是我刚从 MyFonts
  • 使用源映射对缩小的 JS 进行反混淆 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 源映射可以帮助对之前使用 Closure Uglifyjs 缩小的代码进行反混淆吗 源映射的工作方式是否存在真正的障碍 或者只是因为没有人关心它而存在 我不太确定它是否可以以类似
  • Android 中的 iOS 移动配置相当于什么?

    在 iOS 中 我们使用移动配置来控制设备的各个方面 例如 VPN 开启 要求 Webclips Caldav carddav ldap 限制 VPN wifi Email 交换 主动同步 ETC 我们将在下载配置文件时将其托管在网站中 然
  • 从解决方案资源管理器搜索时 Visual Studio 2015 崩溃

    从解决方案资源管理器搜索时 Visual Studio 2015 崩溃 这是已知的错误吗 有什么解决方法吗 我使用的是 Microsoft Visual Studio Professional 2015 版本 14 0 23107 0 从事
  • 获取动态添加的视图的 ID

    如何获取布局中动态添加的View的ID public class Display static int i Dynamic UIActivity dyn private Context context View mField null Te
  • 测试静态 jsonp 响应

    我在发出 jsonp 请求时没有遇到任何问题 但是我不确定是否设置 Web 服务以在 jsonp 中传递响应 首先 服务器是否需要以某种方式配置以允许 jsonp 请求 或者页面只需要正确格式化响应 在我的测试中 我收到了来自 geonam
  • DI/IoC、NHibernate 并帮助它们协同工作

    我正在尝试了解 DI IoC NHibernate 并让它们在我正在开发的应用程序中很好地协同工作 我对 NHibernate 和 DI IoC 都很陌生 所以不太确定我正在做的事情是否是明智的做法 这是场景 该应用程序为用户提供了计算特定
  • 是否有一个 Django 模板过滤器可以处理“...more”,并且当您单击它时,它会显示更多文本?

    假设我有一个很大的段落 我只想显示前 15 个单词 之后 该人单击 更多 以查看其余内容 刚刚启动它 似乎可以做你想做的事情 并且不依赖任何外部 JS 库 免责声明 我还没有在 IE 中尝试过这个 但 chrome 和 firefox 工作
  • 如何从另一个线程更新 GUI 上的文本框[重复]

    这个问题在这里已经有答案了 我是 C 新手 我正在尝试制作一个简单的客户端服务器聊天应用程序 我的客户端窗口窗体上有 RichTextBox 我正在尝试从另一个类中的服务器更新该控件 当我尝试这样做时 我收到错误 跨线程操作无效 控制 te