如果一个方法被一个线程调用,由于业务需要,另一个线程也需要用到这个方法怎么办呢?
如果直接在另一个线程中调用该方法,不一定会报错,但是肯定不会执行,因此很难发现问题出在哪里。
本菜目前知道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线程下的消息框信息了!