从不是在我的业务类中创建的线程的线程访问控件"progressBar1" [英] Control 'progressBar1' accessed from a thread other than the thread it was created on in my business class

查看:73
本文介绍了从不是在我的业务类中创建的线程的线程访问控件"progressBar1"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在另一个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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆