我在线程中使用 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;
}
}
}