JsonConvert.DeserializeObject阻止UI线程

时间:2016-02-15 12:54:47

标签: .net vb.net multithreading asynchronous json.net

以下VB.NET代码使用Newtonsoft JSON.NET库并在按钮单击事件处理程序中执行并阻止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 个答案:

答案 0 :(得分: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线程,您可以在操作完成时处理数据表。但请记住,您的事件处理程序将立即返回,ContinueWith处理程序将在以后触发。因此,您可能需要相应地调整UI(禁用按钮等)。

编辑: 更新了代码示例以反映DoomVroom的建议

更新: 为了响应OP的更新,我建议创建一个视图,并首先只加载一些记录。当用户滚动或页面时,添加更多记录。一次添加500多条记录会压倒UI线程,您会遇到阻塞。

答案 1 :(得分: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()