繁体   English   中英

C#线程和属性

[英]c# threads and properties

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

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

谢谢!

我建议您在点击处理程序中捕获它们,并将它们传递给新线程的委托。 对于实际的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)
        {
            ...
        }
    }
}

您发布的代码不需要其他任何内容。 但是,只有在线程运行时没有其他代码可以访问令牌成员时,它才能正常工作。 对变量的共享读/写访问需要通过锁来保护。 但这还不是全部,您还必须确保线程正确同步,读取“令牌”的线程可能应该等到工作线程更新值为止。 通过Google搜索“生产者消费者模式”,您会发现很多有关该主题的文献。

假设在这种情况下,UI线程中需要某种代码来等待RequestImage()完成,然后使用其结果,处理同步的最简单方法是让RequestImage()在完成时调用Control.BeginInvoke()。工作。

请注意,您还需要处理在工作线程完成之前UI线程终止的情况。 不这样做可能会产生ObjectDisposed异常。 针对该问题的解决方案是将线程的IsBackground属性设置为True。 确保确保线程中止时不会发生任何令人讨厌的事情。

声明共享变量volatile就足够了。

编辑:有人可以解释为什么这不是一个好答案吗? 我认为令牌应该是易变的。 否则,GUI线程可能会使用缓存的值。

将方法的签名更改为void RequestImage(对象状态),然后调用t.Start(this)将表单的实例传递到线程主体中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM