martijn_himself
martijn_himself

Reputation: 1570

JsonConvert.DeserializeObject blocks UI thread

The following VB.NET code uses the Newtonsoft JSON.NET library and executes in a button click event handler and blocks the UI thread:

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

I've tried to use different syntax (Task.Run etc.) but it still blocks the UI thread. What is the correct syntax to use here?

EDIT: it turns out the UI is actually blocking when the DataSource is being set for a DataGridView UI component. There are only 500 records in the DataTable used to populate the DataGridView. Why is the UI blocking when performing this task, i.e.

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

Thanks

Upvotes: 1

Views: 477

Answers (2)

Eric
Eric

Reputation: 950

I would try removing the Async keyword from your event handler, and using the ContinueWith method and see if that helps. Example:

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)

This won't block your UI thread, and you can process the data table when the operation is complete. Keep in mind though, that your event handler will immediately return, and the ContinueWith handler will fire at a later time. So you may have to adjust your UI accordingly (disable buttons, etc..)

EDIT: Updated code example to reflect DoomVroom's suggestion

UPDATE: In response to the OP's update, I would suggesting creating a view, and loading only a few records in it at first. As the user scrolls or pages, add some more records into it. Adding 500+ records all at once overwhelms the UI thread and you experience the blocking.

Upvotes: 2

Paulo Morgado
Paulo Morgado

Reputation: 14856

Try this:

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()

Upvotes: 1

Related Questions