[英]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.