循环与线程的写法

7年 2020-07-09 05:11:46
我有这样一个需求,循环执行2个操作,这2个操作一个是timer定时器,一个是thread。需求是循环执行这个2个操作。应该怎么写这个方法呢?使用for循环执行2个操作,这样会没等到操作执行完,循环就继续运行了,求大神指点
...全文
1946 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghui0380 2020-07-10
  • 打赏
  • 举报
回复
引用 11 楼 年轻的程序员小唐 的回复:
请问这段代码怎么测试信号量是否阻止的呢,这段代码该怎么理解,我每次按button2都有输出是不是表示信号量没阻止
这个需要理解“异步”这个词,也就是awati/async 这一组词的含义,这词表明 “我有个任务给你做,你先去做。我等你做完了通知我,我接着做后面的步骤。同时在你做的过程,我可以做其他的事情” 写那段代码是表示红字的含义。也就是这里整天所谓正确答案“我卡了”----------“开线程”,但是我们说其实答案并不是开线程,答案其实应该是“异步”,你我可以同时处理多件事情,而不是我同步等着你完成(同步意味着我就等着你完成,这段时间我啥都不做,就等着你)
  • 打赏
  • 举报
回复
引用 9 楼 wanghui0380 的回复:
  private static readonly SemaphoreSlim slim = new SemaphoreSlim(1);
        private async void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {

                await slim.WaitAsync();
                Trace.WriteLine("准备进入新线程");
                RegisterThread();
            }
        }

        void RegisterThread()
        {
            
            Thread thread=new Thread(RegisterThread0);
            thread.Start();
        }

        void RegisterThread0()
        {
            
            Thread.Sleep(TimeSpan.FromMinutes(1));
            Trace.WriteLine("线程执行完毕,释放信号量");
            slim.Release();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Trace.WriteLine("测试信号量是否阻止,主进程运行");
        }
这是你现有代码直接加异步信号锁,看上去还是很讨厌。依旧诡异。而且因为需要异步,所以我还是用了await 下面我在贴,直接“未来时态”代码,你看是不是比这种诡异代码看着顺眼多了
请问这段代码怎么测试信号量是否阻止的呢,这段代码该怎么理解,我每次按button2都有输出是不是表示信号量没阻止
wanghui0380 2020-07-09
  • 打赏
  • 举报
回复
private async void button1_Click(object sender, EventArgs e) { for (int i = 0; i < 10; i++) { await RegisterThread(); } } Task RegisterThread() { return Task.Run(() => { Trace.WriteLine("进入线程"); Thread.Sleep(TimeSpan.FromMinutes(1)); Trace.WriteLine("线程执行完毕"); }); } private void button2_Click(object sender, EventArgs e) { Trace.WriteLine("测试信号量是否阻止,主进程运行"); }
wanghui0380 2020-07-09
  • 打赏
  • 举报
回复
  private static readonly SemaphoreSlim slim = new SemaphoreSlim(1);
        private async void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {

                await slim.WaitAsync();
                Trace.WriteLine("准备进入新线程");
                RegisterThread();
            }
        }

        void RegisterThread()
        {
            
            Thread thread=new Thread(RegisterThread0);
            thread.Start();
        }

        void RegisterThread0()
        {
            
            Thread.Sleep(TimeSpan.FromMinutes(1));
            Trace.WriteLine("线程执行完毕,释放信号量");
            slim.Release();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Trace.WriteLine("测试信号量是否阻止,主进程运行");
        }
这是你现有代码直接加异步信号锁,看上去还是很讨厌。依旧诡异。而且因为需要异步,所以我还是用了await 下面我在贴,直接“未来时态”代码,你看是不是比这种诡异代码看着顺眼多了
八爻老骥 2020-07-09
  • 打赏
  • 举报
回复
感觉你的Timer用错地方了,去掉Timer直接Thread.Sleep起到定时的作用,或者将Thread.join(),ManualResetEvent等待线程返回。如果.net版本比较新的话,直接使用Task执行任务,执行任务期间调用Wait方法,等待任务完成。
7年 2020-07-09
  • 打赏
  • 举报
回复
引用 6 楼 wanghui0380 的回复:
实际上
if (0 != threadrunning)
{
this.rtbFinger.Text = "注册或验证线程运行中!";
return false;
}

threadrunning += 1;

你这代码就已经是“信号量”的影子了

帮忙写个小例子吧,谢谢了
wanghui0380 2020-07-09
  • 打赏
  • 举报
回复
实际上 if (0 != threadrunning) { this.rtbFinger.Text = "注册或验证线程运行中!"; return false; } threadrunning += 1; 你这代码就已经是“信号量”的影子了
wanghui0380 2020-07-09
  • 打赏
  • 举报
回复
当我们习惯“未来时态”编程的时候,在看这种代码就别扭了。 好了,这里还没准备好接受“未来时态”的编程。所以俺们也就不说了,免得那几个“5年新人”又要喷口水。 很明显,你用线程是因为你不想堵着,你用timer是因为你不知道这个线程啥时候结束的。 如果用“未来时态”编程,其实就简单几句话,因为他自己就能表示“将来某个时刻我准备好了或者我失败了” 至于你这里,我只能说。既然结果是异步拿到的,那么直接用异步信号量堵上就行了(去掉所谓的timer,我们已经很烦这里整日整夜的,没完没了的,那几个5年新人的口里的所谓标准答案了-------什么4种timer如何如何)
7年 2020-07-09
  • 打赏
  • 举报
回复
我现在是这么写的

for (int i = 0; i < visitorList.Count; i++)
{
Monitor.Enter(obj);
visitor_name = visitorList[i].f_name;
if (isRunNum == 0)
{
//定时器执行
idTimer.enable=true;

if (readIDCardCompleted)
{
WeiDunFingerTool wdTool = new WeiDunFingerTool();

wdTool.featureRegister = featureRegister;
wdTool.showMessage = ShowWndMessageMethod;
wdTool.setParam = SetParamMethod;
wdTool.setVisitorFingerInfo = setVisitorFingerInfoMethod;
wdTool.featureLen = featureLen;
if (!wdTool.OpenDevice())
{
this.rtbFinger.Text = "打开指静脉设备失败!";
return false;
}
if (0 != threadrunning)
{
this.rtbFinger.Text = "注册或验证线程运行中!";
return false;
}

threadrunning += 1;
//线程执行
wdTool.RegisterThread();
}
}

但是这样每次都是内容没执行完,就继续循环了。我这种写法是不是不对?得怎么写啊
正怒月神 2020-07-09
  • 打赏
  • 举报
回复
直接2个都是winform的timer不就好了。还要循环什么?
OrdinaryCoder 2020-07-09
  • 打赏
  • 举报
回复
没有看懂 你的意思是执行完一个操作之后再执行另一个操作?

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧