gpt4 book ai didi

c# - 信号量线程

转载 作者:行者123 更新时间:2023-11-30 22:28:46 25 4
gpt4 key购买 nike

我在线程中使用 Semaphore 时遇到问题。这是我的情况,我想在当前 3 个线程中更改 ListViewItem 的背景颜色,然后在一段时间后变成另一种颜色使用 PauseForMilliSeconds 然后在 1 完成后释放另一个线程,这样我就可以将最大线程执行限制为 3 个线程,但问题是应用程序不会响应。

这是我的代码

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Threading;

namespace _Sample__Using_Semaphore
{
public partial class frmMain : Form
{
Semaphore semaphore = new Semaphore(0, 3);

public frmMain()
{
InitializeComponent();
}

private void frmMain_Load(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
ListViewItem lvi = new ListViewItem(new string[] { i.ToString(), "Ready", "0" });
lvItems.Items.Add(lvi);
}
}

private void btnStartStop_Click(object sender, EventArgs e)
{
semaphore.Release(3);

for (int i = 0; i < lvItems.Items.Count; i++)
{
WorkerThread(i);
}
}

private Thread WorkerThread(int startNum)
{
Thread t = new Thread(() => WorkerProcess(startNum));
t.Start();

return t;
}

private void WorkerProcess(int startNum)
{
Invoke((MethodInvoker)delegate()
{
ProcessMe(startNum);
});
}

private void ProcessMe(int index)
{
Random rand = new Random();

semaphore.WaitOne();

lvItems.Items[index].BackColor = Color.Red;

PauseForMilliSeconds(rand.Next(500, 5000));

lvItems.Items[index].BackColor = Color.Yellow;

semaphore.Release(1);
}

public DateTime PauseForMilliSeconds(int MilliSecondsToPauseFor)
{
DateTime ThisMoment = DateTime.Now;
TimeSpan duration = new TimeSpan(0, 0, 0, 0, MilliSecondsToPauseFor);
DateTime AfterWards = ThisMoment.Add(duration);

while (AfterWards >= ThisMoment)
{
System.Windows.Forms.Application.DoEvents();
ThisMoment = DateTime.Now;
}

return DateTime.Now;
}
}
}

对我的问题有什么帮助或解决方案吗?

解决方案:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Threading;

namespace _Sample__Using_Semaphore
{
public partial class frmMain : Form
{
Semaphore semaphore = new Semaphore(0, 3);

public frmMain()
{
InitializeComponent();
}

private void frmMain_Load(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
ListViewItem lvi = new ListViewItem(new string[] { i.ToString(), "Ready", "0" });
lvItems.Items.Add(lvi);
}
}

private void btnStartStop_Click(object sender, EventArgs e)
{
semaphore.Release(3);

foreach (ListViewItem lvi in lvItems.Items)
{
WorkerThread(lvi.Index);
}
}

private Thread WorkerThread(int startNum)
{
Thread t = new Thread(() => WorkerProcess(startNum));
t.Start();

return t;
}

private void WorkerProcess(int startNum)
{
ProcessMe(startNum);
}

private void ProcessMe(int index)
{
Random rand = new Random();

semaphore.WaitOne();

Invoke((MethodInvoker)delegate()
{
lvItems.Items[index].BackColor = Color.Red;
});

PauseForMilliSeconds(rand.Next(500, 5000));

Invoke((MethodInvoker)delegate()
{
lvItems.Items[index].BackColor = Color.Yellow;
});

semaphore.Release(1);
}

public DateTime PauseForMilliSeconds(int MilliSecondsToPauseFor)
{
DateTime ThisMoment = DateTime.Now;
TimeSpan duration = new TimeSpan(0, 0, 0, 0, MilliSecondsToPauseFor);
DateTime AfterWards = ThisMoment.Add(duration);

while (AfterWards >= ThisMoment)
{
System.Windows.Forms.Application.DoEvents();
ThisMoment = DateTime.Now;
}

return DateTime.Now;
}
}
}

最佳答案

我认为您的问题来自放错位置的调用。通过这样做,您实际上是在被 sleep 调用阻塞的主线程中执行 Process me 代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{

public partial class Form1 : Form
{
Semaphore semaphore = new Semaphore(0, 3);
public Form1()
{
InitializeComponent();
myDelegate = new ChangeBack(ChangeBackMethod);
}

private void frmMain_Load(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
ListViewItem lvi = new ListViewItem(new string[] { i.ToString(), "Ready", "0" });
lvItems.Items.Add(lvi);
}
}

private void btnStartStop_Click(object sender, EventArgs e)
{
semaphore.Release(3);

for (int i = 0; i < lvItems.Items.Count; i++)
{
WorkerThread(i);
}
}

private Thread WorkerThread(int startNum)
{
Thread t = new Thread(new ParameterizedThreadStart(WorkerProcess));
t.Start(startNum);

return t;
}

private void WorkerProcess(object startNum)
{

ProcessMe((int)startNum);

}

private void ProcessMe(int index)
{
Random rand = new Random();

semaphore.WaitOne();


lvItems.BeginInvoke(myDelegate, index, Color.Red);

Thread.Sleep(rand.Next(500, 5000));

lvItems.BeginInvoke(myDelegate, index, Color.Yellow);

semaphore.Release();

}
public delegate void ChangeBack(int index, Color c);
private ChangeBack myDelegate;
private void ChangeBackMethod(int index, Color c)
{

lvItems.BeginUpdate();
((ListViewItem)(lvItems.Items[index])).BackColor = c;
lvItems.EndUpdate();
}

public DateTime PauseForMilliSeconds(int MilliSecondsToPauseFor)
{
DateTime ThisMoment = DateTime.Now;
TimeSpan duration = new TimeSpan(0, 0, 0, 0, MilliSecondsToPauseFor);
DateTime AfterWards = ThisMoment.Add(duration);

while (AfterWards >= ThisMoment)
{
//System.Windows.Forms.Application.DoEvents();
ThisMoment = DateTime.Now;
}

return DateTime.Now;
}
}
}

关于c# - 信号量线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10623199/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com