WinForm启用线程问题

@adens 4/28/2017 8:12:50 AM

问题描述

在制作winform的页面是需要点击按钮轮询不断的从接口获取数据保存数据库,直接写个循环会阻塞当前UI线程,导致winform页面不能再进行其他操作. 解决方案 使用Thread开启另外一个线程执行循环查询保存功能

1.Thread的基本用法

Thread td;//声明线程
td = new Thread(()=>{
  //do something
});//线程将要执行方法
td.IsBackground = true;//设为后台任务
td.Start();//开始执行
td.Abort();//结束线程

这样就执行了一个基本的线程 根据实际需要添加一个开始按钮和结束按钮 //声明一个全局Thread

Thread td;
private void StartBtn_Click(object sender, EventArgs e)
{
    td = new Thread(()=>{
      //do something
    });//线程将要执行方法
    td.IsBackground = true;//设为后台任
    if (!td.IsAlive)//线程运行状态
    {
       td.Start();
    }
}
private void EndBtn_Click(object sender, EventArgs e)
{
  
    if (td.IsAlive)//线程运行状态
    {
       td.Abort();
    }
}

附加问题

在线程中没法操作页面.会报错:Winform线程间操作无效从不是创建控件的线程访问它 比如在线程中执行TextBox的赋值

 //错误做法
 td = new Thread(()=>{
      //do something 错误的做法
      this.TestBox.Text = "我想给他一个值"
});

附加问题解决方案

//声明一个赋值方法
private void SetText(string infos)
{
 //在这个线程中唤起控件
  if (this.TestBox.InvokeRequired)
  {
    Action<string> action = new Action<string>(SetText);
                Invoke(action, new object { infos });
  }
  else
  {
    this.TestBox.Text= infos;
  }
}
//在线程中执行
 td = new Thread(()=>{
      //do something 
      SetText("我想给他一个值")
});

全部代码

public partial class TestForm : Form
{
  Thread td;
  //声明一个赋值方法
  private void SetText(string infos)
  {
   //在这个线程中唤起控件
    if (this.TestBox.InvokeRequired)
    {
      Action<string> action = new Action<string>(SetText);
                  Invoke(action, new object { infos });
    }
    else
    {
      this.TestBox.Text= infos;
    }
  }
  public void Btn_Click(object sender, EventArgs e)
  {
    if(td.IsAlive){
      this.Btn.Text="结束线程"
    }else{
      this.Btn.Text="开始线程"
    }
    td = new Thread(()=>{
      //do something
      SetText(DateTime.Now.ToString())
    });//线程将要执行方法
    td.IsBackground = true;//设为后台任
    if (!td.IsAlive)//线程运行状态
    {
       td.Start();
    }else{
      td.Abort();
    }
  }
}

Last Modification : 4/28/2017 8:12:50 AM


In This Document