C#WinForm与此同时开启三个线程数据出现混乱
C#WinForm同时开启三个线程数据出现混乱。
是这样的,我要操作三台斑马打印机(假如是A,B,C三台打印机)打印三种标签纸,为了加快速度,我同时开启了3个线程,一台打印机对应一个线程,但是现在数据出现了混乱,包括线程里面的全局变量,有时候本该A打印的东西却被打印机B打印出来,还有就是有时候打印机不打印。
对于这个问题,我换成了顺序打印,不采用多线程,然后就正常了。但是我还是想用多线程,请大家,高手们帮我看看我下面的程序,最好能修改下程序中不对的地方。解决(找出)我多线程中的问题。
因为字数限制,线程threadreport12,threadreport13当中的代码没有贴出来,这2个线程当中的代码跟threadreport11中的差不多
------解决思路----------------------
使用队列存储,依次打印。
------解决思路----------------------
if (!report1Flag)
这样传有个说法叫闭包,你应该将它作为thread的参数传入,因为你这个随时都会在变,所以会错位
------解决思路----------------------
如果我线程1没执行完,那线程2中以上设置是不是就变了?线程2改变了一些参数的时候线程1执行的时候是不是就是线程2东西?
------解决思路----------------------
这个就不知道了
看你这种代码都有的……
TSCLIB_DLL.clearbuffer();
------解决思路----------------------
threadreport11.Start(obj);
这里可以传递参数,但貌似就不能用匿名委托了,你得定义个一个方法来接受参数
如果NET版本高的话,可以用Task
------解决思路----------------------
在合适的地方加锁,
lock
{
}
是这样的,我要操作三台斑马打印机(假如是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
{
}