我想从工作线程中读取两个属性。这是一个类的例子:
public partial class FrmPrincipal : Form
{
private int Height;
private int Width;
private string token;
public FrmPrincipal()
{
InitializeComponent();
...
}
private void menuItem1_Click(object sender, EventArgs e)
{
Thread t = new Thread(RequestImage);
t.Start();
}
private void RequestImage()
{
try
{
...
// I want to read these properties
int alto = this.Height;
int ancho = this.Width;
this.token = "...";
...
}
catch (Exception ex)
{
...
}
}
当menuItem1_Click它被执行时,它使用方法RequestImage启动一个新线程。在这个方法中我需要读取this.Height和this.Width并更新this.token的值。
我该怎么做?
我正在为windows mobile(Compact Framework 2.0)编写应用程序。
谢谢!
答案 0 :(得分:4)
我建议你在点击处理程序中捕获它们,并将它们传递给新线程的委托。使用实际ThreadStart的lambda表达式最容易做到这一点:
public partial class FrmPrincipal : Form
{
private string token;
public FrmPrincipal()
{
InitializeComponent();
...
}
private void menuItem1_Click(object sender, EventArgs e)
{
int width = Width;
int height = Height;
Thread t = new Thread(() => RequestImage(width, height));
t.Start();
}
private void RequestImage(int width, int height)
{
try
{
...
int alto = height;
int ancho = width;
this.token = "...";
...
}
catch (Exception ex)
{
...
}
}
}
答案 1 :(得分:2)
您发布的代码不需要任何其他内容。但是,只有在线程运行时没有其他代码才能访问令牌成员时,它才能正常工作。对变量的共享读/写访问需要通过锁保护。但这不是全部,您还必须确保线程正确同步,读取“令牌”的线程应该等到工作线程更新值。谷歌的“生产者消费模式”,你会发现很多关于这个主题的文献。
假设在这种情况下你需要UI线程中的某种代码来等待RequestImage()完成,然后使用它的结果,处理同步的最简单方法是让RequestImage()调用Control.BeginInvoke()当它完成工作时。
请注意,您还需要处理UI线程在工作线程完成之前终止的情况。不这样做可能会产生ObjectDisposed异常。 Q& D解决方案是将线程的IsBackground属性设置为True。确保线程中止时不会发生任何令人讨厌的事情。
答案 2 :(得分:0)
声明将声明共享变量volatile。
修改强> 有人可以解释为什么这不是一个好的答案?我认为令牌应该是不稳定的。否则GUI线程可以使用缓存值。
答案 3 :(得分:0)
将方法的签名更改为void RequestImage(对象状态) 并调用t.Start(this)将表单的实例传递给线程体。