2016-02-15 49 views
1

以下VB.NET代碼使用Newtonsoft JSON.NET圖書館和一個按鈕單擊事件處理程序,並執行塊UI線程:JsonConvert.DeserializeObject塊UI線程

Dim table As DataTable = 
Await Task.Factory.StartNew(Function() JsonConvert.DeserializeObject(of DataTable)(result)) 

我試着用不同的語法(Task.Run等),但它仍然阻塞UI線程。這裏使用的正確語法是什麼?

編輯:事實證明,當爲DataGridView UI組件設置DataSource時,UI實際上是阻塞的。 DataTable中只有500條記錄用於填充DataGridView。爲什麼UI執行此任務時阻塞,即

Dim dv As DataView = table.DefaultView 
DataGridView1.DataSource = dv 

感謝

+2

這似乎是正確的有比電話,可能是導致塊更多的代碼? – DoomVroom

+0

@DoomVroom有可能會造成運行但Windows窗體的代碼是一個插件類的大型Windows應用程序 - 內運行內部執行塊會不會是客戶端應用程序以某種方式阻止插件沒有其他代碼類創建新線程?我將如何去檢測?謝謝! –

+0

在我使用JsonConvert的過程中,不需要很長時間。我不知道你要轉換多大的表格。我可能會模擬一個測試反序列化你的數據表。只需對錶進行單元測試,然後反序列化以查看需要多長時間。看看測試是否符合你的期望。我也假設你在你的函數中也使用了Async,因爲你的代碼沒有聲明它。 – DoomVroom

回答

2

我會嘗試從你的事件處理程序移除Async關鍵字,並使用ContinueWith方法,看看有沒有什麼幫助。 例子:

Dim context = TaskScheduler.FromCurrentSynchronizationContext() 
Dim t = Task.Factory.StartNew(Function() JsonConvert.DeserializeObject(Of DataTable)(result)) 

t.ContinueWith(Sub(res) 
    If res.Result IsNot Nothing Then 
     ' Do something with your data table 
    End If 
End Sub, context) 

這不會阻止你的UI線程,並且可以處理數據表時,操作完成。請記住,您的事件處理程序會立即返回,並且稍後會處理該事件處理程序。所以,你可能需要相應地調整你的UI(禁用按鈕,等..)

編輯: 更新的代碼示例,以反映DoomVroom的建議

UPDATE: 爲響應OP的更新,我會建議建立一個首先查看並加載其中的幾條記錄。隨着用戶滾動或翻頁,在其中添加更多記錄。一次添加超過500條記錄會淹沒UI線程並遇到阻塞。

+1

做這個方法應該可以工作,但是如果你想做UI工作,一定要使用在UI線程中傳遞的重載。 – DoomVroom

+0

謝謝,我更新了我的例子。你是對的,在UI線程中訪問控件而不通過UI線程會拋出異常。 – Eric

+0

非常感謝您的建議。這仍然會阻塞UI線程約8秒,同時gridview的數據源被設置。 –

1

試試這個:

Dim table As DataTable = 
    Await Task.Run(
     Function() JsonConvert.DeserializeObject(of DataTable)(result)) 

Dim si As ISupportInitialize = DataGridView1 
si.BeginInit() 
DataGridView1.DataSource = table.DefaultView 
si.EndInit() 
+0

Thansk!我試過這個,但是在數據源被設置的時候它仍然會阻塞大約8秒。 –

+1

嘗試禁用網格視圖。或者在批量中添加到網格視圖。 –