2016-02-15 52 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

尝试禁用网格视图。或者在批量中添加到网格视图。 –