【第22期】观点:IT 行业加班,到底有没有价值?

跨线程调用问题

原创 2015年11月20日 10:04:56

如果一个方法被一个线程调用,由于业务需要,另一个线程也需要用到这个方法怎么办呢?

如果直接在另一个线程中调用该方法,不一定会报错,但是肯定不会执行,因此很难发现问题出在哪里。

本菜目前知道2种方法:1、用委托,看起来比较高大上一点;2、直接另写一个方法,绕过其线程(局限性非常大,如果是语言自身的消息机制等根本就绕不过)

下面我根据C# Winform的用其他线程更改提示框信息把第一种方法写一下吧!

首先添加一个借口:

    /// <summary>
    /// 消息接口
    /// </summary>
    public interface IShowMessage
    {
        /// <summary>
        /// 展示信息
        /// </summary>
        /// <param name="Message_"></param>
        void Message(object Message_);
    }

同时定义一个委托:

 /// <summary>
    /// 消息机制
    /// </summary>
    /// <param name="Message_"></param>
    public delegate void ShowMessages(object Message_);


然后让winform继承这个接口

public partial class frmTest : Form, IShowMessage



此时就需要重新借口的 Message方法啦!注意下面红色标记的正是上文中定义的委托。

    public void Message(object Message_)
        {            
            ShowMessages Show = new ShowMessages(M);
            if (Show != null)
                this.Invoke(Show, Message_);
        }

如果直接传message为string的话,只要下面写一下M函数就完事了啦!

   private void M(object Message_)
        {
            //var message = new { Message = "", date = new DateTime() };
            //message = Message_.ToAnonymous(message);
            //txtMsg.AppendText("\r\n" + message.date + "\r\n" + message.Message);
            txtMsg.AppendText(message);
        }

如果要传多个参数(如上文中注释的代码):如下得重写一下字符串扩展StringExtend

 /// <summary>
    /// 字符串扩展方法
    /// </summary>
    public static class StringExtend
    {
        /// <summary>
        /// 匿名类的转化,转换成对应的格式
        /// </summary>
        /// <typeparam name="T">匿名类的类型</typeparam>
        /// <param name="Value_">数据</param>
        /// <param name="t_">匿名类的类型</param>
        /// <returns></returns>
        public static T ToAnonymous<T>(this object Value_, T t_)
        {
            return (T)Value_;
        }
    }

这样我们就可以把Message_定义为一个对象,包含2个或多个参数:new { Message = "", date = new DateTime() };



调用方法:在需要调用到的线程类中定义接口对象:如下重写一个方法ShowMessage()通过接口调用Message()方法

IShowMessage _IShow = null;

/// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="Message_"></param>
        /// <param name="time_"></param>
        private void ShowMessage(string Message_, DateTime time_)
        {
            var message = new { Title = Message_, Date = DateTime.Now };
            _IShow.Message(message);
        }

调用只要写:

ShowMessage("出现异常", DateTime.Now);

便可以在其他线程中更改winform线程下的消息框信息了!





版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

多线程委托之跨线程问题分析--在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke(解决方法已更新)

多线程委托之跨线程问题分析 今天在写一个程序测试运行跨线程同步的时候出一个异常信息。 异常信息:System.InvalidOperationException “在创建窗口句柄之前,不能在控件上调...

pyqt信号槽的问题,GUI线程之外调用GUI的操作

在gui线程之外要使用QLineEdit.appendPlainText 不能直接将GUI对象带入到线程中,直接调用, 需要使用信号槽, 在GUI线程之外用信号启动槽 如: [code="python"] #先定义信号 不能在__init__构造函数中定义,需...
  • scnjl
  • scnjl
  • 2012-10-05 11:03
  • 2289

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

C#跨线程调用窗体控件的问题

前段时间遇到跨线程调用窗体控件的问题,其实一句话System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;就可以解决,但...

跨线程中调用winform窗体控件

由于 Windows 窗体控件本质上不是线程安全的。因此如果有两个或多个线程适度操作某一控件的状态(set value),则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用和死锁的情况。于是在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,...

C#跨线程调用窗体控件的问题

前段时间遇到跨线程调用窗体控件的问题,其实一句话System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;就可以解决,但...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)