C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别
C# 最基本的涉及模式(单例模式)
//密封,保证不能继承
public sealed class Xiaohouye
{
//私有的构造函数,保证外部不能实例化
private Xiaohouye()
{
}
//防止多线程,并发
private static object syncObj = new object();
//我们在给类型中创建一个静态实例。当用户需要该类型的实例时,我们就返回这个实例
private static Xiaohouye instance = null;
public static Xiaohouye Instance
{
//获取实例
get
{
// if 判断保证了唯一性:实现在第一次调用instance 时候才会创建类型的唯一实例,不会每一次调用都创建实例
if (instance == null)
{
// lock 是为了在多线程环境下保证仍然是一个实例,我们应该在判断实例是否已经创建,以及在实例还没有创建的时候创建一个实例的语句上加一个同步锁,当实例已经创建之后,就不需要再做加锁操作了
lock (syncObj)
{
//保证对象永远只有一个
if (instance == null)
instance = new Xiaohouye();
}
}
return instance;
}
}
}
C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案:
1.按同一顺序访问对象
2.尽量能减少就减少数据库操作次数
3.如果某一个动作响应太慢,可使用多线程操作,来提高速度
4.添加try catch 异常捕捉机制,如果发生死锁,肯定会抛出异常,在异常种 sleep几秒后重新执行该过程
C#关闭应用程序时如何关闭子线程
托管线程或者是后台线程,或者是前台线程。后台线程不会使托管执行环境处于活动状态,除此之外,后台线程与前台线程是一样的。一旦所有前台线程在托管进程(其中 .exe 文件是托管程序集)中被停止,系统将停止所有后台线程并关闭。通过设置 Thread.IsBackground 属性,可以将一个线程指定为后台线程或前台线程。例如,通过将 Thread.IsBackground 设置为 true,就可以将线程指定为后台线程。同样,通过将 IsBackground 设置为 false,就可以将线程指定为前台线程。从非托管代码进入托管执行环境的所有线程都被标记为后台线程。通过创建并启动新的 Thread 对象而生成的所有线程都是前台线程。如果要创建希望用来侦听某些活动(如套接字连接)的前台线程,则应将Thread.IsBackground 设置为 true,以便进程可以终止。
一个线程或者是后台线程或者是前台线程。后台线程与前台线程类似,区别是后台线程不会阻止进程终止。一旦属于某一进程的所有前台线程都终止,公共语言运行库就会通过对任何仍然处于活动状态的后台线程调用 Abort 来结束该进程。
C#中 ThreadStart和ParameterizedThreadStart区别
最主要区别:
1.Thread 是启动一个线程,但是没有参数。
2.ParameterThreadStart 线程可以接受一个输入参数
ThreadStart:
ThreadStart这个委托定义为void ThreadStart(),也就是说,所执行的方法不能有参数。
ThreadStart threadStart=new ThreadStart(ProcessData); Thread thread=new Thread(threadStart); thread.Start(); public void SayHelloToXiaohouye() { string strName="My name is Xiaohouye";
Console.Write("Hello "+strName); }
上面很简单的例子,我们用定义了一个ThreadStart类型的委托,这个委托制定了线程需要执行的方法: SayHelloToXiaohouye,在这个方法里声明一个变量,并输出.这就构成了最简单的多线程的例子,一般情况下,我们都是用这个的。
ParameterThreadStart:
ParameterThreadStart的定义为void ParameterizedThreadStart(object state),使用这个这个委托定义的线程的启动函数可以接受一个输入参数,具体例子如下 :
ParameterizedThreadStart threadStart=new ParameterizedThreadStart(SayHelloToXiaohouye) Thread thread=new Thread() ; thread.Start("Xiaohouye");
//注意参数一定要用object 类型,否则报错 public void SayHelloToXiaohouye(object name) {
//使用时候需要转换 Console.Write("Hello my name is {0}",name.ToString()); }
看了一个参数的例子,下面我们来看下多个参数的例子
,我们通过把多个参数组合到一个类中,然后把这个类的实例作为参数传递,就可以实现多个参数传递,废话不多说,看代码:
public class AddParameter { public string a=string.Empty;
public string b=string.Empty; public AddParameter(string name1, string name2) { a = name1; b = name2; } } #endregion class Program { static void Main(string[] args) { Console.WriteLine("***** Adding with Thread objects *****"); Console.WriteLine("当前线程为:{0}", Thread.CurrentThread.ManagedThreadId); AddParameter p = new AddParameter("xiaohouye", "xiaowangzi"); Thread t = new Thread(new ParameterizedThreadStart(Add)); t.Start(p); Console.ReadLine(); } #region Add method
//组合参数 static void Add(object data) { if (data is AddParams) { Console.WriteLine("当前线程为:{0}",Thread.CurrentThread.ManagedThreadId); AddParameter ap = (AddParameter )data; Console.WriteLine("{0} + {1} is {2}", ap.a, ap.b, ap.a + ap.b); } } #endregion } }