从不是在我的业务类中创建的线程的线程访问控件"progressBar1" [英] Control 'progressBar1' accessed from a thread other than the thread it was created on in my business class
问题描述
我在另一个dll中有一个方法,该方法可以获取大量数据(砍掉22,000行),并且需要为用户创建一个进度条.
I have a method in another dll that gets a lot of data (lopping 22k rows), and I need to create a progress bar for the user.
如果我不异步调用此方法,它将挂起应用程序.但是当我异步调用它时,我收到了错误progressBar1
从其他线程访问的错误,而不是在其上创建的线程
If I do not call this method asynchronously it hangs the application. But when I call it asynchronously I get the error progressBar1
Control accessed from a thread other than the thread it was created on
private void btnSend_Click(object sender, EventArgs e)
{
string filePath = tbPath.Text;
ETLBusiness etlBusiness = new ETLBusiness(filePath);
Task.Run(() => etlBusiness.LoadData(progressBar1));
}
在这种情况下,backgroundWorker1.RunWorkerAsync
不是异步的,它使我的应用程序停止循环
In that case, backgroundWorker1.RunWorkerAsync
is not asynchronous, it is stopping my application in looping
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访问它.这是不行".尝试以下代码
Your problem is that your control exists on thread A but you are trying to access it via thread B. This is a 'no-no'. Try the following code
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的类型
Where 'ProgressBar1ObjectType' is the Type of progressBar1
这是另一个可能效果更好的选择:
Here is another option that may work better:
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"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!