スレッドでセマフォを使用する際に問題があります。これが私の状況です。現在の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;
}
}
}