C#线程问题 我点击按钮,开一个线程(传参),线程方法体是一个循环,线程结束后,继续点击按钮重开线程。线程跑着发现我传的参是之前的参数(前面跑的参数是正常的,中间偶发参数改变)。请问这是什么原因造成的。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我方法体里面有执行标志,为true时我break循环,然后退出 bool a1 = true; private void Form7_Load(object sender, EventArgs e) { while (a1) { Thread thred = new Thread(too); thred.Start(); //启动线程 thred.IsBackground=true; }如這樣。當我們想停止就直接讓a1為false可以了 我方法体里面有执行标志,为true时我break循环,然后退出代碼呢,截圖看看 添加标志位 比如为true的时候 弹提示框线程没结束 为false的时候 点击按钮正常启动线程 在线程开始置true 在结束置false 我方法体里面有执行标志,为true时我break循环,然后退出代碼呢,截圖看看 ClassName cm = new ClassName(); cm.Name = fileName; if (isUseCamer) { QueryDataForMS qdf = new QueryDataForMS(); GetMarkParams(qdf, fileNo); } Thread tMain = new Thread(new ParameterizedThreadStart(RunForPrint)); tMain.IsBackground = true; tMain.Start(cm); private void RunForPrint(object str) { if (str is ClassName) { ClassName cmT = (ClassName)str; if (connectMLCb.Checked) { isRun = true; while (!alarmFlag) { if (!connectMLCb.Checked) { break; } DateTime startTime = DateTime.Now; DateTime endTime; string txtPrintCount = GetTbPrintCountText(); string txtNudPrePrintCount = GetNudPrePrintCountText(); int tIntPrintCount = Convert.ToInt32(txtPrintCount); int tIntNudPrePrintCount = Convert.ToInt32(txtNudPrePrintCount); if (tIntNudPrePrintCount <= tIntPrintCount) { tIntPrintCount -= tIntNudPrePrintCount; printCountSum = 0; } if (loadedFlag) { break; } do { Thread.Sleep(50); } while (!loaded); if (catchFlag) { break; } if (!RunForMachine1(cmT.Name)) { break; } if (alarmFlag) { break; } Thread tThread = new Thread(new ThreadStart(HandDoWork)); tThread.IsBackground = true; tThread.Start(); do { Thread.Sleep(50); } while (!updownOver); updownOver = false; endTime = DateTime.Now; int timeCount = (endTime - startTime).Minutes * 60 + (endTime - startTime).Seconds; timeShowTb.Invoke((Action)delegate { timeShowTb.Text = timeCount.ToString(); }); Thread countThread = new Thread(new ThreadStart(ThreadCount)); countThread.IsBackground = true; countThread.Start(); printCountSum += 1; tbPrintCount.Invoke((Action)delegate { tbPrintCount.Text = printCountSum.ToString(); }); if (tIntNudPrePrintCount == printCountSum) { printCountFlag = true; break; } } isRun = false; } } }代码有点多 我有加标志位判断,但是我开线程时那个标志位是false的 if(!isRun ){ Thread tMain = new Thread(new ParameterizedThreadStart(RunForPrint)); tMain.IsBackground = true; tMain.Start(cm);}看了一下 你线程内部是有标志位 但是没看见你用到这个isRun 在启动线程的时候判断一下 为false的时候再启动线程 private void startBtn_Click(object sender, EventArgs e) { RecoderLog("点击了启动按钮"); if (!CheckStatus()) { return; } Run(); } private void Run() { if (isRun) { return; } if (runFlag == 0) { return; } if (alarmFlag) { return; } string fileNo = fileName; if (string.IsNullOrEmpty(fileNo)) { return; } ClassName cm = new ClassName(); cm.Name = fileName; if (isUseCamer) { QueryDataForMS qdf = new QueryDataForMS(); GetMarkParams(qdf, fileNo); } Thread tMain = new Thread(new ParameterizedThreadStart(RunForPrint)); tMain.IsBackground = true; tMain.Start(cm); } } private void RunForPrint(object str) { if (str is ClassName) { ClassName cmT = (ClassName)str; if (connectMLCb.Checked) { isRun = true; while (!alarmFlag) { if (!connectMLCb.Checked) { break; } DateTime startTime = DateTime.Now; DateTime endTime; string txtPrintCount = GetTbPrintCountText(); string txtNudPrePrintCount = GetNudPrePrintCountText(); int tIntPrintCount = Convert.ToInt32(txtPrintCount); int tIntNudPrePrintCount = Convert.ToInt32(txtNudPrePrintCount); if (tIntNudPrePrintCount <= tIntPrintCount) { tIntPrintCount -= tIntNudPrePrintCount; printCountSum = 0; } if (loadedFlag) { break; } do { Thread.Sleep(50); } while (!loaded); if (catchFlag) { break; } if (!RunForMachine1(cmT.Name)) { break; } if (alarmFlag) { break; } Thread tThread = new Thread(new ThreadStart(HandDoWork)); tThread.IsBackground = true; tThread.Start(); do { Thread.Sleep(50); } while (!updownOver); updownOver = false; endTime = DateTime.Now; int timeCount = (endTime - startTime).Minutes * 60 + (endTime - startTime).Seconds; timeShowTb.Invoke((Action)delegate { timeShowTb.Text = timeCount.ToString(); }); Thread countThread = new Thread(new ThreadStart(ThreadCount)); countThread.IsBackground = true; countThread.Start(); printCountSum += 1; tbPrintCount.Invoke((Action)delegate { tbPrintCount.Text = printCountSum.ToString(); }); if (tIntNudPrePrintCount == printCountSum) { printCountFlag = true; break; } } isRun = false; } } }之前是传值类型,我后来改成传引用类型了。还是有问题 if (alarmFlag) { break; }你這個只是退出循環罢了,根本没有停止线程的啊。你应该这样 Thread tMain;全局變量bool loadedFlag=true;全局變量再次點擊按鈕事件 if (loadedFlag) { tMain = null; } tMain = new Thread(new ParameterizedThreadStart(RunForPrint)); tMain.IsBackground = true; tMain.Start(cm); public void RunForPrint() { while (!loadedFlag) { if (!connectMLCb.Checked) { loadedFlag=true; } //等等 //thred = null; } } 一样的问题https://bbs.csdn.net/topics/392748710“别和陌生人说话”---------------否则风险自负。所谓别和陌生人说话的概念-------一个方法就只改用别人传递给他的,他自己内部的,他自己创建的别人传递给他的------------当参数传的他自己内部的----------比如你上个帖子,人家建议你的,从新封装一个对象,你要起什么线程,在这个对象里玩。他自己创建的-------------------他自己内部new的对象你非要跨越-------非要说调用外面的一个参数-----------既然是调用外面的参数。那么外面可不管你,外面那些东西可不是线程安全的 所以,你开线程,传递一个公用对象,线程在开线程,而且里面还依赖一大堆公用对象所以最终就是碰运气,期盼人家没改新对象 xx=new 新对象新对象.xxxxxx=你想传达的东西xx.方法1=>{这个对象的这个方法在来,此时每次都是new的新对象,他跟别人没关系,他不依赖外面} 参见:https://blog.csdn.net/rocklee/article/details/78423505 我在里面建了一个对象,private void RunForPrint(object str) { if (str is ClassName) { ClassName cmT = (ClassName)str;这样都会被污染吗 基于SSM框架的论坛怎么实现 不要用thread,thread不太容易判断线程什么时候结束,用backgroundworker或者task就方便许多。 用task比较简单,判断task状态就行 你的代码,混写了一大堆的东西,我们也不知道你想干嘛,然后到底哪里是你说的“什么东西修改了,偶尔是以前的”我想问一下,你到底想干的是什么,那东西是要同步,还是异步。同时你愿意接受线程这种老语法,还是愿意接受task,async/wait这类新语法。然后我们在来说后面的 如果你愿意接受新语法,这东西很简单我现在就可以手写demo(伪代码)async button_Click(){ 参数对象封装 xx=new 参数对象封装() await 处理(xx)}async task 处理( 参数对象封装 xx){ //这里你可以放锁控制,当然你到底想怎么弄我们不知道到,所以不给你东西,因为这种东西选择很多,需要考虑是同步/异步,用锁还是用信号量,并行的还是互斥的 //这里放你前面那一大串东西 var res= await xxxxxxxxx(另一个参数) //这里是号称的另一个需要很长时间处理的东西 //后面接着做你需要的什么更新UI那一堆操作} C#中提示UPDATE语法错误,求救!!! 怎么在运行的窗体里输入的数据能保存起来,下次运行还能看见? 控件开发,如果不继承Form或者是Control,鼠标移动事件怎么写 ListView怎么设置Report模式啊? 关于让菜单变灰不可用的问题!怎么设置? winfrom 回车事件 gentle不支持无主键的表 我想在某个时间段自动重启某个程序,请问脚本怎么写呢? 江湖救急,关于导出XML文档的问题 ■☆■两个问题,有熟悉C# DrawLines和VB、C#的DateTime类型的高人请来帮个忙(在线) C#exp导出 求助 insertrow之后后端获取到的行数不变
private void Form7_Load(object sender, EventArgs e)
{ while (a1)
{
Thread thred = new Thread(too);
thred.Start(); //启动线程
thred.IsBackground=true;
}
如這樣。當我們想停止就直接讓a1為false可以了
代碼呢,截圖看看
代碼呢,截圖看看 ClassName cm = new ClassName();
cm.Name = fileName;
if (isUseCamer)
{
QueryDataForMS qdf = new QueryDataForMS();
GetMarkParams(qdf, fileNo);
}
Thread tMain = new Thread(new ParameterizedThreadStart(RunForPrint));
tMain.IsBackground = true;
tMain.Start(cm);
private void RunForPrint(object str)
{
if (str is ClassName)
{
ClassName cmT = (ClassName)str;
if (connectMLCb.Checked)
{
isRun = true;
while (!alarmFlag)
{
if (!connectMLCb.Checked)
{
break;
}
DateTime startTime = DateTime.Now;
DateTime endTime; string txtPrintCount = GetTbPrintCountText();
string txtNudPrePrintCount = GetNudPrePrintCountText();
int tIntPrintCount = Convert.ToInt32(txtPrintCount);
int tIntNudPrePrintCount = Convert.ToInt32(txtNudPrePrintCount);
if (tIntNudPrePrintCount <= tIntPrintCount)
{
tIntPrintCount -= tIntNudPrePrintCount;
printCountSum = 0;
}
if (loadedFlag)
{
break;
}
do
{
Thread.Sleep(50);
} while (!loaded); if (catchFlag)
{
break;
}
if (!RunForMachine1(cmT.Name))
{ break; }
if (alarmFlag)
{
break;
}
Thread tThread = new Thread(new ThreadStart(HandDoWork));
tThread.IsBackground = true;
tThread.Start();
do
{
Thread.Sleep(50);
} while (!updownOver); updownOver = false;
endTime = DateTime.Now;
int timeCount = (endTime - startTime).Minutes * 60 + (endTime - startTime).Seconds;
timeShowTb.Invoke((Action)delegate
{
timeShowTb.Text = timeCount.ToString();
});
Thread countThread = new Thread(new ThreadStart(ThreadCount));
countThread.IsBackground = true;
countThread.Start();
printCountSum += 1;
tbPrintCount.Invoke((Action)delegate
{
tbPrintCount.Text = printCountSum.ToString();
});
if (tIntNudPrePrintCount == printCountSum)
{
printCountFlag = true;
break;
}
}
isRun = false;
}
}
}代码有点多
{
Thread tMain = new Thread(new ParameterizedThreadStart(RunForPrint));
tMain.IsBackground = true;
tMain.Start(cm);
}
看了一下 你线程内部是有标志位 但是没看见你用到这个isRun 在启动线程的时候判断一下 为false的时候再启动线程
{
RecoderLog("点击了启动按钮");
if (!CheckStatus())
{
return;
}
Run();
}
private void Run()
{
if (isRun)
{
return;
}
if (runFlag == 0)
{
return;
}
if (alarmFlag)
{
return;
} string fileNo = fileName;
if (string.IsNullOrEmpty(fileNo))
{
return;
}
ClassName cm = new ClassName();
cm.Name = fileName;
if (isUseCamer)
{
QueryDataForMS qdf = new QueryDataForMS();
GetMarkParams(qdf, fileNo);
}
Thread tMain = new Thread(new ParameterizedThreadStart(RunForPrint));
tMain.IsBackground = true;
tMain.Start(cm);
}
}
private void RunForPrint(object str)
{
if (str is ClassName)
{
ClassName cmT = (ClassName)str;
if (connectMLCb.Checked)
{
isRun = true;
while (!alarmFlag)
{
if (!connectMLCb.Checked)
{
break;
}
DateTime startTime = DateTime.Now;
DateTime endTime; string txtPrintCount = GetTbPrintCountText();
string txtNudPrePrintCount = GetNudPrePrintCountText();
int tIntPrintCount = Convert.ToInt32(txtPrintCount);
int tIntNudPrePrintCount = Convert.ToInt32(txtNudPrePrintCount);
if (tIntNudPrePrintCount <= tIntPrintCount)
{
tIntPrintCount -= tIntNudPrePrintCount;
printCountSum = 0;
}
if (loadedFlag)
{
break;
}
do
{
Thread.Sleep(50);
} while (!loaded); if (catchFlag)
{
break;
}
if (!RunForMachine1(cmT.Name))
{ break; }
if (alarmFlag)
{
break;
}
Thread tThread = new Thread(new ThreadStart(HandDoWork));
tThread.IsBackground = true;
tThread.Start();
do
{
Thread.Sleep(50);
} while (!updownOver); updownOver = false;
endTime = DateTime.Now;
int timeCount = (endTime - startTime).Minutes * 60 + (endTime - startTime).Seconds;
timeShowTb.Invoke((Action)delegate
{
timeShowTb.Text = timeCount.ToString();
});
Thread countThread = new Thread(new ThreadStart(ThreadCount));
countThread.IsBackground = true;
countThread.Start();
printCountSum += 1;
tbPrintCount.Invoke((Action)delegate
{
tbPrintCount.Text = printCountSum.ToString();
});
if (tIntNudPrePrintCount == printCountSum)
{
printCountFlag = true;
break;
}
}
isRun = false;
}
}
}
之前是传值类型,我后来改成传引用类型了。还是有问题
{
break;
}
你這個只是退出循環罢了,根本没有停止线程的啊。
你应该这样 Thread tMain;全局變量
bool loadedFlag=true;全局變量
再次點擊按鈕事件
if (loadedFlag)
{
tMain = null;
}
tMain = new Thread(new ParameterizedThreadStart(RunForPrint));
tMain.IsBackground = true;
tMain.Start(cm);
public void RunForPrint()
{
while (!loadedFlag)
{
if (!connectMLCb.Checked)
{
loadedFlag=true;
}
//等等
//thred = null;
}
}
https://bbs.csdn.net/topics/392748710
“别和陌生人说话”---------------否则风险自负。所谓别和陌生人说话的概念-------一个方法就只改用别人传递给他的,他自己内部的,他自己创建的别人传递给他的------------当参数传的
他自己内部的----------比如你上个帖子,人家建议你的,从新封装一个对象,你要起什么线程,在这个对象里玩。
他自己创建的-------------------他自己内部new的对象
你非要跨越-------非要说调用外面的一个参数-----------既然是调用外面的参数。那么外面可不管你,外面那些东西可不是线程安全的
新对象.xxxxxx=你想传达的东西
xx.方法1=>{这个对象的这个方法在来,此时每次都是new的新对象,他跟别人没关系,他不依赖外面}
我在里面建了一个对象,
private void RunForPrint(object str)
{
if (str is ClassName)
{
ClassName cmT = (ClassName)str;
这样都会被污染吗
然后我们在来说后面的
{
参数对象封装 xx=new 参数对象封装()
await 处理(xx)
}async task 处理( 参数对象封装 xx)
{
//这里你可以放锁控制,当然你到底想怎么弄我们不知道到,所以不给你东西,因为这种东西选择很多,需要考虑是同步/异步,用锁还是用信号量,并行的还是互斥的
//这里放你前面那一大串东西
var res= await xxxxxxxxx(另一个参数) //这里是号称的另一个需要很长时间处理的东西
//后面接着做你需要的什么更新UI那一堆操作
}