c#线程和属性

时间:2009-02-20 13:13:47

标签: c# winforms multithreading

我想从工作线程中读取两个属性。这是一个类的例子:

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)编写应用程序。

谢谢!

4 个答案:

答案 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)将表单的实例传递给线程体。