线程不起作用,它冻结我的应用程序[重复]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程不起作用,它冻结我的应用程序[重复]相关的知识,希望对你有一定的参考价值。
这个问题与以下内容完全相同:
我有一个带有几个循环和数据库查询的函数,我想通过传递一个进度条来异步调用它来向用户显示进度。
当我调用线程程序挂起时,我甚至无法关闭
当我调用synchContext.Post(state => etlBusiness.LoadData(progressBar),null);它冻结了,将loadData的逻辑带到UI是不可行的,有许多方法被称为内部
public partial class Home : Form
{
public Home()
{
InitializeComponent();
synchronizationContext = System.Threading.SynchronizationContext.Current;
}
private SynchronizationContext synchronizationContext;
public SynchronizationContext context = SynchronizationContext.Current;
public Thread _myThread = null;
private void btnSend_Click(object sender, EventArgs e)
{
_myThread = new Thread(() => LoadData(synchronizationContext, progressBar1));
_myThread.Start();
}
private void LoadData(System.Threading.SynchronizationContext synchContext, ProgressBar progressBar)
{
string filePath = tbPath.Text;
ETLBusiness etlBusiness = new ETLBusiness(filePath);
synchContext.Post(state => etlBusiness.LoadData(progressBar), null);
_myThread.Abort();
}
}
你不需要使用Thread.Abort()
,SynchronizationContext
甚至使用“异步”代码(我假设你指的是你不能调用的await
/ async
,除非你的目标API实际上提供了真正的异步功能,请注意使用Task.Run
不一样事情):WinForms具有内置功能,可以在Invoke
/ BeginInvoke
方法的UI线程中运行代码。
对于进度报告,我不建议传递ProgressBar
,因为这是一个脆弱的设计,意味着你的内部业务逻辑依赖于WinForms,这阻止你在WPF,ASP.NET或无头进程中使用它;相反,你可以有一个通过回调更新UI的私有方法,如下所示:
private ProgressBar progressBar;
public Home()
{
this.InitializeComponent();
}
private void btnSend_Click( Object sender, EventArgs e )
{
Task.Run( (Action)this.LoadData )
}
private void UpdateProgress( Float progress )
{
if( this.InvokeRequired )
{
this.BeginInvoke( (Action<Float>)this.UpdateProgress, progress );
return;
}
this.progressBar.Value = progress * this.progressBar.Maximum;
}
private void LoadData()
{
ETLBusiness etlBusiness = new ETLBusiness(filePath);
etlBusiness.LoadData( this.UpdateProgress ); // You'll need to replace its progressBar parameter with a callback to `this.UpdateProgress`.
}
你的ETLBusiness.LoadData
方法应改为:
void LoadData( Action<Float> progressCallback );
又是我。我在你上一篇文章中发表了评论。问题来自我的解决方案。发生的事情是你正在创建和启动一个线程,然后你用synchContext.Post()将ETLBusiness.LoadData()的逻辑发送回主线程。需要做的是以下两个选项之一:
- 将ETLBusiness.LoadData()的逻辑移动到Form.LoadData()(线程调用的方法),然后使用synchContext.Post(state => progressBar1.SetPercent())专门更新progressBar。
- 将线程移动到ETLBusiness类。并使用synchContext.Post(state => progressBar1.SetPercent())专门更新progressBar。
再次抱歉,此问题来自我之前发布的解决方案
以上是关于线程不起作用,它冻结我的应用程序[重复]的主要内容,如果未能解决你的问题,请参考以下文章