我正在尝试创建一个不断检查值更改的线程,然后在GUI中直观地显示PictureBox中的更改。
我实际写的内容有点复杂,所以我在保留基本想法的同时简化了它,如果这还不够,我很乐意提供澄清:
public class CheckPictures
{
PictureBox update;
List<String> check;
public CheckPictures(PictureBox anUpdate, List<String> aCheck)
{
update = anUpdate;
check = aCheck;
}
public void start()
{
while(true)
{
if (aCheck[0] == "Me")
{
update.Image = Image.fromFile("");
}
}
}
}
static int Main(string[] args)
{
List<String> picturesList = new List<String>();
CheckPictures thread1 = new CheckPictures(PictureBox1, picturesList);
Thread oThread1 = new Thread(thread1.start));
}
我想要它做的是动态更改PictureBox1中的图片,如果我要添加字符串&#34;我&#34;到pictureList。上面的代码并没有像我希望的那样工作。我原以为通过传递实际的PictureBox和List,对其他地方的List的任何更改都是程序会被线程捕获。所以我的第一个问题是:这可能吗?如果是这样,我需要对我的代码做出哪些改变才能实现它?
答案 0 :(得分:2)
您可能想要使用事件。您注册了一个事件处理程序,当一个线程中的某些内容发生更改时,它会调用另一个线程中的事件处理程序来完成工作忙着等待浪费cpu。
答案 1 :(得分:1)
你明确地不想做无限循环,这只会消耗cpu:
while(true)
{
if (aCheck[0] == "Me")
{
update.Image = Image.fromFile("");
}
}
我认为你应该研究CountdownLatch课程。
public class CountdownLatch
{
private int m_remain;
private EventWaitHandle m_event;
public CountdownLatch(int count)
{
m_remain = count;
m_event = new ManualResetEvent(false);
}
public void Signal()
{
// The last thread to signal also sets the event.
if (Interlocked.Decrement(ref m_remain) == 0)
m_event.Set();
}
public void Wait()
{
m_event.WaitOne();
}
}
这里的基本思想是你需要在线程上停止执行一段时间,并在满足某个条件时恢复(可能在另一个线程上)。
换句话说,你将有一个计数器,在某个条件下递减它的值,每当它变为零时你激活你的事件,执行一些代码然后重新开始(停止执行并等待计数器变为零) 。
在您的情况下,您可以将计数器设置为1并在设置aCheck[0] = "Me";
时减小其值。这样您就不会浪费CPU。
伪代码:
初始化计数器:
CountdownLatch latch = new CountdownLatch(1);
让线程等待:
public void start()
{
while(true)
{
latch.Wait(); //execution stops
{
//execution resumes once the latch counter is zero.
if (aCheck[0] == "Me") //double check you have what you need
{
update.Image = Image.fromFile("");
latch = new CountdownLatch(1); //reset if you need to do it again
}
}
}
}
只要满足您的条件(即aCheck[0] = "Me";
),就会发出信号:
latch.Signal();
这最后一行将使线程恢复执行。好东西。
答案 2 :(得分:1)
创建一些对象,在添加新图片时会引发事件。例如。代表图片集的类:
public class PicturesCollection
{
public event EventHandler<PictureAddedEventArgs> PictureAdded;
private List<string> _pictures = new List<string>();
public void Add(string name)
{
_pictures.Add(name);
if (PictureAdded != null)
PictureAdded(this, new PictureAddedEventArgs(name));
}
public IEnumerable<string> Pictures
{
get { return _pictures; }
}
}
如果要为事件提供一些其他数据,请创建自定义EventArgs:
public class PictureAddedEventArgs : EventArgs
{
public PictureAddedEventArgs(string name)
{
Name = name;
}
public string Name { get; private set; }
}
现在您只需要 - 创建图片集并订阅该活动:
static int Main(string[] args)
{
PicturesCollection pictures = new PicturesCollection();
pictures.PictureAdded += Pictures_PictureAdded;
}
static void Pictures_PictureAdded(object sender, PictureAddedEventArgs e)
{
if (e.Name == "Me")
PictureBox1.Image = Image.fromFile("");
}
如果你在应用程序中添加一个新的图片集合,它将引发PictureAdded事件,你可以处理和更新PictureBox。在这种情况下,CPU不会浪费。