[英]What is the best way to thread work in c#?
在c#中使用线程工作(方法)的最佳方法是什么?
例如:
假设我有一个表单,并希望从db加载数据。
My form controls:
- dataGridView (to show data from DB),
- label (loading status) and
- button (start loading).
当我单击按钮时,我的表单将被冻结,直到任务完成。 在任务完成之前,加载状态也不会改变。 我认为异步线程会是答案吗?
所以我的问题是:处理这个问题的最佳方法是什么? 我知道有很多关于线程的东西,但是它们之间的区别是什么?你如何使线程安全?
你是如何解决这类问题的?
最好的祝福。
如果使用Windows窗体,则应查看BackrgroundWorker 。 更一般地说,使用ThreadPool类通常很有用。 最后,值得一看的是新的.NET 4的Parallel类。
没有通用的“最佳”方式来处理工作。 你只需要尝试不同的做事方式,我担心。
我特别喜欢Jeremy D. Miller 在本页描述的延续思想(向下滚动以找到“延续”部分)。 它非常优雅,意味着编写非常少的样板代码。
基本上,当您使用Func参数调用“ExecuteWithContinuation”时,该函数将异步执行,然后在完成时返回一个操作。 然后将操作编组回您的UI线程以充当延续。 这允许您快速将操作拆分为两位:
需要一点时间来适应,但它很酷。
public class AsyncCommandExecutor : ICommandExecutor
{
private readonly SynchronizationContext m_context;
public AsyncCommandExecutor(SynchronizationContext context)
{
if (context == null) throw new ArgumentNullException("context");
m_context = context;
}
public void Execute(Action command)
{
ThreadPool.QueueUserWorkItem(o => command());
}
public void ExecuteWithContinuation(Func<Action> command)
{
ThreadPool.QueueUserWorkItem(o =>
{
var continuation = command();
m_context.Send(x => continuation(), null);
});
}
}
然后你就这样使用它(原谅格式......)
public void DoSomethingThatTakesAgesAndNeedsToUpdateUiWhenFinished()
{
DisableUi();
m_commandExecutor.ExecuteWithContinuation(
() =>
{
// this is the long-running bit
ConnectToServer();
// This is the continuation that will be run
// on the UI thread
return () =>
{
EnableUi();
};
});
}
你可以使用这种模式: -
private void RefreshButton_Click(object sender, EventArgs e)
{
MessageLabel.Text = "Working...";
RefreshButton.Enabled = false;
ThreadPool.QueueUserWorkItem(delegate(object state)
{
// do work here
// e.g.
object datasource = GetData();
this.Invoke((Action<object>)delegate(object obj)
{
// gridview should also be accessed in UI thread
// e.g.
MyGridView.DataSource = obj;
MessageLabel.Text = "Done.";
RefreshButton.Enabled = true;
}, datasource);
});
}
您无法从分离线程中运行的代码访问您的控件 - 框架不允许这样做,这解释了您获得的错误。
您需要在非表单对象中缓存从db检索的数据,并在后台工作线程完成后使用该对象的数据填充UI(并处理访问该对象的同步)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.