控制'progressBar1'从我在业务类中创建的线程以外的线程访问[duplicate]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了控制'progressBar1'从我在业务类中创建的线程以外的线程访问[duplicate]相关的知识,希望对你有一定的参考价值。
这个问题在这里已有答案:
我在另一个dll中有一个方法可以获取大量数据(占用22k行),我需要为用户创建一个进度条。
如果我不异步调用此方法,它会挂起应用程序。但是,当我异步调用它时,我得到错误progressBar1
控件从一个线程访问,而不是它创建的线程
private void btnSend_Click(object sender, EventArgs e)
{
string filePath = tbPath.Text;
ETLBusiness etlBusiness = new ETLBusiness(filePath);
Task.Run(() => etlBusiness.LoadData(progressBar1));
}
在这种情况下,backgroundWorker1.RunWorkerAsync
不是异步的,它在循环中停止我的应用程序
private void btnSend_Click(object sender, EventArgs e)
{
string filePath = tbPath.Text;
ETLBusiness etlBusiness = new ETLBusiness(filePath);
Func<ProgressBar,int> func = etlBusiness.LoadData;
this.backgroundWorker1.RunWorkerAsync(func(progressBar1));
}
怎么修好了?
答案
你的问题是你的控件存在于线程A上,但你试图通过线程B访问它。这是一个'禁忌'。请尝试以下代码
private void btnSend_Click(object sender, EventArgs e)
{
Task.Run(() => LoadData(System.Threading.SynchronizationContext.Current, progressBar1));
}
private void LoadData (System.Threading.SynchronizationContext synchContext, ProgressBar1ObjectType progressBar)
{
string filePath = tbPath.Text;
ETLBusiness etlBusiness = new ETLBusiness(filePath);
synchContext.Post(state => etlBusiness.LoadData(progressBar), null);
}
其中'ProgressBar1ObjectType'是progressBar1的类型
这是另一种可能更好的选择:
Thread _myThread = null;
private void btnSend_Click(object sender, EventArgs e)
{
SynchronizationContext synchContext = SynchronizationContext.Current;
_myThread = new Thread(() => LoadData(synchContext, progressBar1));
myThread.Start();
}
private void LoadData (System.Threading.SynchronizationContext synchContext, ProgressBar1ObjectType progressBar)
{
string filePath = tbPath.Text;
ETLBusiness etlBusiness = new ETLBusiness(filePath);
synchContext.Post(state => etlBusiness.LoadData(progressBar), null);
_myThread.Abort();
}
以上是关于控制'progressBar1'从我在业务类中创建的线程以外的线程访问[duplicate]的主要内容,如果未能解决你的问题,请参考以下文章