C#WinForm与此同时开启三个线程数据出现混乱

C#WinForm同时开启三个线程数据出现混乱。
是这样的,我要操作三台斑马打印机(假如是A,B,C三台打印机)打印三种标签纸,为了加快速度,我同时开启了3个线程,一台打印机对应一个线程,但是现在数据出现了混乱,包括线程里面的全局变量,有时候本该A打印的东西却被打印机B打印出来,还有就是有时候打印机不打印。

对于这个问题,我换成了顺序打印,不采用多线程,然后就正常了。但是我还是想用多线程,请大家,高手们帮我看看我下面的程序,最好能修改下程序中不对的地方。解决(找出)我多线程中的问题。


if (checkBox1.Checked == true)
               {
                   if (report1_printmaclist.Count == 2)
                   {
                       report1Flag = true;                       
                   }
               }//threadreport1 = new Thread(new ThreadStart(delegate { Report1DelegateMethod(mac); }))
               if (report2_printsnlist.Count == 2)
               {
                   report2Flag = true;
               }
              
              //开始打印模板1
              threadreport11 = new Thread(new ThreadStart(delegate
                  {
                      try
                      {
                          if (!report1Flag)
                          {
                              return;
                          }
                          if (Report1.ControlByName("Barcode1") != null && Report1.ControlByName("Barcode2") != null)
                          {
                              //-----------设置设备MAC标签----------------------------------------------
                              Report1.ControlByName("Barcode1").AsBarcode.Text = report1_printmaclist[0];
                              Report1.ControlByName("Barcode2").AsBarcode.Text = report1_printmaclist[1];
                              //Report1.Print(true);//开始打印设备MAC标签
                              report1controllist.Clear();
                              this.Invoke(new EventHandler(delegate
                                  {
                                      this.GetControlProperty(Report1, report1controllist);
                                  }));
                              Thread.Sleep(200);
                              TSCLIB_DLL.openport(report1printername);
                              TSCLIB_DLL.setup("64", "9", report1printerspeed, report1printerdensity, "0", "3", "0");                          //Setup the media size and sensor type info
                              TSCLIB_DLL.sendcommand("SET CUTTER OFF");
                              TSCLIB_DLL.sendcommand("DIRECTION 1");//出纸方向 
                              TSCLIB_DLL.clearbuffer();
                              int barcode_count = 0;
                              foreach (ControlProperty item in report1controllist)
                              {
                                  if (item.ControlType == "grctBarcode")
                                  {
                                      TSCLIB_DLL.barcode(((int)(Convert.ToDecimal(item.ControlLocationLeft) * 80)).ToString(), ((int)(Convert.ToDecimal(item.ControlLocationTop) * 80)).ToString(), "128M", ((int)(Convert.ToDecimal(item.ControlHeight) * 80) - item.ControlModelPoint * 2.4 - 4.0).ToString(), "3", "0", "1", "2", "!103" + report1_printmaclist[barcode_count]);
                                      barcode_count++;
                                  }
                                  if (item.ControlType == "grctStaticBox" || item.ControlType == "grctMemoBox")
                                  {
                                      TSCLIB_DLL.windowsfont((int)(Convert.ToDecimal(item.ControlLocationLeft) * 80), (int)(Convert.ToDecimal(item.ControlLocationTop) * 80), (int)(item.ControlModelPoint * 2.4), 0, 0, 0, item.ControlTextFont, item.ControlText);
                                  }
                              }
                              TSCLIB_DLL.printlabel("1", report1printcount);     //Print labels                                          
                              TSCLIB_DLL.closeport();
                              report1_printmaclist.Clear();
                              report1Flag = false;

                              //------------------------------------------------------------------------                     
                          }
                          else
                          {
                              labWarning.Invoke((MethodInvoker)delegate()
                              {
                                  labWarning.Text = "提示:设备MAC标签不含有控件Barcode1或Barcode2";
                                  labWarning.ForeColor = Color.Red;
                              });
                              maclist.RemoveAt(maclist.Count - 1);
                              return;
                          }
                      }
                      catch (Exception ex)
                      {
                          MessageBox.Show(ex.Message);
                      }
                  }));
              threadreport11.Start();
              
                 threadreport12= new Thread(new ThreadStart(delegate
                  {
                      //打印模板2的代码跟线程1的差不多
                  }));
               threadreport12.Start();

                threadreport13= new Thread(new ThreadStart(delegate
                  {
                      //打印模板3,线程3
                 }));
               threadreport13.Start();



因为字数限制,线程threadreport12,threadreport13当中的代码没有贴出来,这2个线程当中的代码跟threadreport11中的差不多
------解决思路----------------------
使用队列存储,依次打印。
------解决思路----------------------
if (!report1Flag)
这样传有个说法叫闭包,你应该将它作为thread的参数传入,因为你这个随时都会在变,所以会错位
------解决思路----------------------
 TSCLIB_DLL.openport(report1printername);
                              TSCLIB_DLL.setup("64", "9", report1printerspeed, report1printerdensity, "0", "3", "0");                          //Setup the media size and sensor type info
                              TSCLIB_DLL.sendcommand("SET CUTTER OFF");
                              TSCLIB_DLL.sendcommand("DIRECTION 1");//出纸方向 
                              TSCLIB_DLL.clearbuffer();

如果我线程1没执行完,那线程2中以上设置是不是就变了?线程2改变了一些参数的时候线程1执行的时候是不是就是线程2东西?
------解决思路----------------------
这个就不知道了
看你这种代码都有的……
TSCLIB_DLL.clearbuffer();
------解决思路----------------------
threadreport11.Start(obj);
这里可以传递参数,但貌似就不能用匿名委托了,你得定义个一个方法来接受参数
如果NET版本高的话,可以用Task
------解决思路----------------------
在合适的地方加锁,
lock
{

}