C# 多线程
C# 多线程
介绍
C# 多线程的一些操作:调用、传参、返回值、线程同步
场景举例
1、硅晶片追溯系统
工厂中一台机器分为左右两侧,各项功能一样。且需要和上游系统对接。
2、ffmpeg在直播系统中的运用
系统需要利用ffmpeg像nginx服务器基于Rtmp推送流。需要新开一个线程控制系统推流
线程创建与基本使用
1、Thread类
Thread t = new Thread(new ThreadStart(执行方法));//无参数、无返回值
t.Start();
2、Delegate.BeginInvoke
public delegate string MyDelegate(int a,string b); //有参数,有返回值
MyDelegate dele = new MyDelegate(MyThreadRun2);
IAsyncResult result= dele.BeginInvoke(10, "abcd", null, null);
string a = dele.EndInvoke(result);
button1.Text = a.ToString();
public string MyThreadRun2(int a,string b)
{
return b;
}
3、ThreadPool
ThreadPool.QueueUserWorkItem(new WaitCallback(fun3),3);
跨线程调用
无返回值,无参数
Thread t = new Thread(new ThreadStart(MyFunction));
t.Start();
无返回值,多个参数(实体类赋值方式)
///ffmpegexepath:ffmpeg路径
//inputPath:推送视频路径
//CurrentStreamAddress:推流地址
Ffmpeg tws = new Ffmpeg(ffmpegexepath, inputPath, Global.CurrentStreamAddress);
Thread t = new Thread(new ThreadStart(tws.RunPushLocalVideo));
t.Start();
无返回值,多个参数(委托方式)
MyDelegate dele = new MyDelegate (MyFunction);
dele.BeginInvoke(10,"abcd");
void MyFunction(int count, string str);
有返回值,多个参数
public delegate string MyDelegate(int a,string b);
MyDelegate dele = new MyDelegate(MyThreadRun2);
IAsyncResult result= dele.BeginInvoke(10, "abcd", null, null);
string a = dele.EndInvoke(result);
button1.Text = a.ToString();
public string MyThreadRun2(int a,string b)
{
return b;
}
无返回值,单个参数
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ParameterizedThreadStart(MyThreadRun1));
thread.Start(4); //输入任意string、int等数据类型均可
}
void MyThreadRun1(object a)
{
this.BeginInvoke(new EventHandler(delegate
{
button1.Text = a.ToString();
}));
}
跨线程控件显示
方法1:Control.CheckForIllegalCrossThreadCalls=false;
方法2:委托的Invoke和BeginInvoke。
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(MyThreadRun));
thread.Start();
}
void MyThreadRun()
{
//delegate-Invoke方法
this.Invoke(new EventHandler(delegate
{
button1.Text = "1test";
}));
Thread.Sleep(5000);
//delegate-BeginInvoke方法
this.BeginInvoke(new EventHandler(delegate
{
button1.Text = "1234";
}));
Thread.Sleep(5000);
}
线程池
调用外部方法,传参,无返回值
ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadRun1),"1");//传参无返回值调用方法
void MyThreadRun(object a)
{
//Method
}
直接执行,无参,无返回值
ThreadPool.QueueUserWorkItem((object state) =>
{
//Thread New Method
this.BeginInvoke(new EventHandler(delegate
{
button1.Text = "22";
}));
});
多线程同步
不同线程在运行时在某些时候需要设定执行顺序如:A线程需要等待B线程执行完成后
AutoResetEvent方法
AutoResetEvent ae = new AutoResetEvent(false);//定义一个信号量,表示执行结束,可以释放互斥锁
线程A中:ae.Set();
线程B中:ae.WaitOne();//等待线程A停止
初次之外还有Mutex等方法,详见博客