开发者

F# Silverlight RPC: pre-fill paginated data

开发者 https://www.devze.com 2023-01-10 03:59 出处:网络
Thanks to everybody who has helped over the past few months trying to help me get my silverlight / f# prototype up and running (started in the RC version of VS - Ugh).The last problem we are trying to

Thanks to everybody who has helped over the past few months trying to help me get my silverlight / f# prototype up and running (started in the RC version of VS - Ugh). The last problem we are trying to solve is an RPC issue.

We need to have the ability to paginate RPC calls, such that the first page is requested a开发者_运维百科nd bound to the grid and displayed, while the otehr pages are prefilled in the background and concatenated together. I guess psuedo code would look like this:

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

I appologize for the code above, I tried to make it as F# like as possible (writing in this text window); another flaw is the need to use call backs to bind the data to grids etc.

The question approaches might be used to solve this problem and what is the most approriate?


hmm... something like this? (typing in browser so may contain errors):

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

On UI side it will appear like this (i.e. data - ListBox or some other control)

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

精彩评论

暂无评论...
验证码 换一张
取 消