C#从另一个线程更改主线程的按钮文本

时间:2015-08-13 16:36:32

标签: c# multithreading

我有一个名为Form1的类,其中有一个按钮。现在在那堂课里我又做了一个帖子。

如果我尝试从新线程以任何方式更改按钮,我会收到跨线程错误/异常

new Thread(delegate ()
            {
                while (!DL.HasExited)
                {
                    Thread.Sleep(500);
                }

                File.Delete(folderBrowserDialog1.SelectedPath + @"\Steam\steamcmd.zip");
            //The code below this note is the problem
                button1.Text = "START DOWNLOADING";
                button1.Enabled = true;
            }).Start();

我需要在新线程中使用代码,因为我不希望程序在到达while循环时冻结。

那么如何从其他线程更改按钮文本呢?

4 个答案:

答案 0 :(得分:3)

您无法从其他线程访问ui元素属性。使用button1.BeginInvoke( new MethodInvoker(() => { button1.Text = "START DOWNLOADING"; button1.Enabled = true; }));

public class FirstContext : DbContext
{
    private FirstContext()) { }

    public FirstContext(string ConnectionString, int ID) : base(ConnectionString)
    {
        _ID = ID;
        Database.SetInitializer(new FirstInitializer<FirstContext>());
        Database.Initialize(true);   // probably unnecessary
    }

    private int _ID;

    public DbSet<UserModel> Users { get; set; }
}


public class FirstInitializer<TContext> : DropCreateDatabaseAlways<FirstContext>
{
    protected override void Seed(FirstContext context)
    {
        UserModel user;

        user = new UserModel() { Password = "EDCBA", Username = "User1", Email = "temp@temp.com" };
        context.Users.Add(user);

        user = new UserModel() { Password = "ABCDE", Username = "User2", Email = "temp@temp.com" };
        context.Users.Add(user);

        context.SaveChanges();
        base.Seed(context);
    }
}

FirstContext db = new FirstContext(connectionString, 1);
db.Users.Find("User1");

答案 1 :(得分:0)

使用Invoke()。此函数接受委托(您也可以传递匿名函数)。类似的东西:

Invoke(() => {
    button1.Text = "START DOWNLOADING";
    button1.Enabled = true;});

答案 2 :(得分:0)

实现所需内容的最简单方法是在控件上使用BeginInvoke函数:

SELECT DISTINCT x.* 
           FROM my_table x 
           JOIN my_table y 
             ON y.name = x.name 
            AND y.phone <> x.phone;

答案 3 :(得分:0)

线程并不意味着互相混乱的内存空间 - 因此,您尝试简单地更改文本将失败。但是,我能想到3个解决方案:

  • 使用invoke()

正如其他人在我提前几秒提到的那样,你可以使用invoke来改变另一种形式的文本。但是,如果您想要线程之间的任何更多通信,这将是低效的。

  • 使用共享资源

为了在线程之间进行交谈,您可以使用将用于其通信的公共资源。一个非常基本的例子是从线程向文本文件写入您希望按钮显示的文本,并在几秒钟内从另一个线程读取它并检查更改。有一些更好的方法可以做到这一点,这只是一个例子。如果您希望我向您展示这种方法的示例,请提出要求,我很乐意提供。

  • 使用流程代替线程

Proccesses和线程都允许您需要的multytasking,但是,进程可能会相互干扰。在做出这个决定之前,你应该阅读一些更多的差异,这会留给你 - 你认为哪个更适合这些,一个过程或一个线程?如果你也喜欢我,我会愉快地提供一个使用过程的例子。

祝你好运:)