2010-08-05 75 views
2

感谢所有在过去几个月里帮助过我的人,试图帮助我使Silverlight/f#原型启动并运行(从VS版本开始 - Ugh)。我们试图解决的最后一个问题是RPC问题。F#Silverlight RPC:预填充分页数据

我们需要能够对RPC调用进行分页,这样第一页被请求并绑定到网格并显示,而otehr页面在后台预填充并连接在一起。我猜的伪代码是这样的:

let pageNo = 1 
let page1Data = JsonRpc.getSomeData(pageNo) 

let grid.datasource <- page1Data 
let grid.suspendFiltering <- true 

// run the remainder in background 
let allData : list ref = page1Data ref 
for pageNo in [2..totalPages] 
    allData := allData @ JsonRpc.getSomeData(pageNo) 

let grid.datasource <- allData 
let grid.suspendFiltering <- true 

我appologize对于上面的代码,我试图使它作为F#像越好(在本文撰写窗口);另一个缺陷是需要使用回调将数据绑定到网格等。

问题方法可能用于解决这个问题,什么是最合适的?

+0

Hmmmmm ......我读过这一遍又一遍的问题,并不能找出问题所在。如果你想得到你的整个数据集,请公开一个'JsonRpc.getAllData'方法来做到这一点。你的评论*“另一个缺陷是需要使用回调来将数据绑定到网格”*没有上下文,因为就我所知,你的'JsonRpc.getSomeData'方法看起来像一个同步方法,没有参考到任何地方回调。唯一不寻常的是在循环中使用'@'而不是更习惯''yield! page1Data;页面总页数没有收益! getSomeData(pageNo)]' – Juliet 2010-08-05 18:07:03

+0

我看到了(不像我需要的那么清晰) - 让我们说每个分页请求需要2秒来填充。如果我有10页太长,用户无法等待获取所有数据。所以我想要显示第一页并在后台填入其余的数据集。在这个例子中,为了简单起见,我确实省略了回调。即使在一个更简单的模型中,我仍然需要显示一页数据,获取所有数据,然后将网格重新绑定到整个集合... 这是否澄清事情? – akaphenom 2010-08-06 02:00:57

回答

1

嗯...这样的事情? (在浏览器中输入,所以可能包含错误):

module Loader 

open System 
open System.Threading 

let totalPages = 20 

// emulation of long-running data loading routine 
let private loadPageData (page : int) = 
    async { 
     do! Async.Sleep(1000) 
     return List.replicate 5 page 
    } 

// loader - notifies UI about new data via callback 
let loadAsync (callback : System.Action<_>) = 
    let syncContext = SynchronizationContext.Current 
    let doLoad = async { 

     // load first page and immediately feed it to callback 
     let! page1Data = loadPageData 1 

     do! Async.SwitchToContext syncContext 
     callback.Invoke(ResizeArray<_>(page1Data)) 

     // load remaining data in the background 
     do! Async.SwitchToThreadPool() 
     let allData = ResizeArray<_>(page1Data)    

     for page in 2..totalPages do 
      let! pageData = loadPageData page 
      allData.AddRange(pageData) 

     do! Async.SwitchToContext syncContext 
     callback.Invoke(allData) 
     } 

    Async.Start doLoad 

在UI方面会出现这样的(即数据 - 列表框或其他一些控制)

Loader.loadDataAsync(list => data.ItemSource = list) 
+0

谢谢 - 这实际上看起来像我正在考虑实施的设计之一。我们只需在P1之后加载两次“回调”,然后再打开Pn。我对Async模块的细节并不熟悉 - 但它直截了当,并且可以深入查看它。谢谢。其他人对这种设计有什么想法吗? – akaphenom 2010-08-09 13:40:24