2012-07-11 100 views
2

對於我正在處理的項目,我使用一組DataGridView組件來顯示一些數據。每個DataGridView都有自己的DataTable關聯它。要顯示的數據是定期發送的。我的應用程序必須讀取這些數據,解析它並相應地填充數據網格。因爲我想維護表單的響應能力,所以我在無盡的後臺工作人員中實現了數據接收(阻塞)。從線程更新數據綁定數據表安全嗎?

在後臺worker中,我獲取數據並將其解析/轉換爲適合DataTable的值。現在這是我的問題:目前我將這些值直接分配給DataTable對象。 (所以我從背景工作者的DoWork事件中這樣做)

我想知道這是否有效。我確實有索引超出界限例外,我想知道這是否與此有關。這是一個安全和推薦的方式,或者我應該在我的BackgroundWorker的DoWork事件中使用調用來更新DataTables?

+0

爲什麼你會用這個單線程?看起來你應該爲每個控件使用一個Background Worker。你應該做Invokes,不完全確定你在做什麼,如果你想要更詳細的回覆,請提供代碼。 – 2012-07-11 14:40:56

回答

3

不,.NET WinForm控件的所有屬性(這是假設)影響控件渲染的影響(包括綁定到影響渲染的控件的值)必須在創建控件的線程上進行。

也就是說,有很多時候你會逃避能夠做出改變,但行爲是不可預知的,不推薦。

在您的具體情況,我建議具有處理線程的工作方式,然後元帥DataTable是複製到UI線程副本(通過調用ISynchronizeInvoke interface實現的一個,其Control class工具)並更新UI線程中的網格。

基本上,您會執行網格綁定的DataTable的更新,並使用從後臺線程封送的副本。

+0

我不熟悉WinForms ...但在WPF中,有一個可以在UI線程中運行代碼的調度程序。這不可能與WinForms?把這個調度程序調用的委託中的所有數據更新放進去? – Kek 2012-07-11 14:42:36

+0

@kek是的,你可以做到這一點,但你最終做的是調用後臺線程,然後調用UI線程,然後執行*工作。重點在於,在後臺線程完成所有繁重工作後,您必須將後臺線程的數據編組到UI線程(無論是通過調用Windows窗體中的Invoke還是WPF中的Dispatcher)。 – casperOne 2012-07-11 14:44:30

+0

好的......術語編組對我來說不是很清楚......但是,您必須首先處理數據副本並將其複製到。謝謝澄清...... +1回答的完整性 – Kek 2012-07-11 14:49:39

0

那麼,沒有。 儘管在後臺線程中進行計算是一個非常好的主意,但UI更新應始終在UI線程中完成。

當綁定的DataTable到UI元素,你「給」對這些對象的所有權到UI線程在後臺線程不再對其進行更新

+0

雖然我不直接從線程更新UI,但只綁定到UI組件的結構。所以如果我理解正確,這並不重要,它應該仍然在UI線程中完成? – 2012-07-11 14:41:35

+0

@WilliamW更新結構將導致連鎖反應,導致在UI線程中重新呈現控件。這不應該做。您必須擁有該結構的副本,執行工作,然後將數據封送到主線程,並更新綁定到UI組件的結構。 – casperOne 2012-07-11 14:47:33

+0

編輯答案。 – Kek 2012-07-11 14:50:06

0

公平地說,你不應該更新任何UI從綁定元素一個非ui線程。 雖然很多時候你可能沒有看到任何異常,但如果你這樣做,它從來沒有好的做法,往往會導致異常或更糟糕的是,看不見的錯誤