winform表格变得无法响应

时间:2014-04-17 16:01:52

标签: c# winforms c#-4.0

我正在启动一个线程并更新表单元素,但是下面的代码使表单无法解决,请在这里建议我做错了。

    private void StartTimer()
    {
        Thread t = new Thread(Updates);
        t.IsBackground = true;
        t.Start();
    }

    private void Updates()
    {
        try
        {

            while (true)
            {

                this.Invoke((MethodInvoker)delegate
                    {
                        lblTotalImages.Text = AppHelper.GetTotalCount(textBox1.Text).ToString();
                        if (sitename != null)
                        {

                            lblTotalPosted.Text = AppHelper.GetPostedCount(sitename).ToString();
                           // Application.DoEvents();

                        }
                    });
                Thread.Sleep(1000);

            }

        }
        catch (Exception ex)
        {
        }
    }

编辑------- 感谢@Servy介绍任务并行库,我从来没有在这里使用它解决方案我想出了我使用计时器和任务工厂 ya for .net 4没有库扩展和vs 2010我有这个完美的工作

enter code here private void timer1_Tick(object sender, EventArgs e)
    {

        Task.Factory.StartNew(() => AppHelper.GetTotalCount(textBox1.Text)).ContinueWith(t => lblTotalImages.Text = t.Result.ToString(), TaskScheduler.FromCurrentSynchronizationContext());

        if (sitename != null)
        {
            Task.Factory.StartNew(() => AppHelper.GetPostedCount(sitename)).ContinueWith(t => lblTotalPosted.Text = t.Result.ToString(), TaskScheduler.FromCurrentSynchronizationContext());



        }



    } 

1 个答案:

答案 0 :(得分:2)

您正在调用Invoke内部进行某种长时间运行的非UI操作,这意味着它是在UI线程中完成的。您应该努力只更新UI线程中的UI;确保任何长时间运行的非UI代码都不在UI线程的任何调用之外。

使用await也可以用更简单,更有效的方式编写这个解决方案:

public async void StartTimer()
{
    while (true)
    {
        string text = textBox1.Text;
        lblTotalImages.Text = await Task.Run(() =>
            AppHelper.GetTotalCount(text).ToString());
        if (sitename != null)
        {
            lblTotalPosted.Text = await Task.Run(() =>
                AppHelper.GetPostedCount(sitename).ToString());
        }
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}