F # Silverlight RPC: предварительное заполнение разбитых на страницы данных - PullRequest
2 голосов
/ 05 августа 2010

Спасибо всем, кто помогал в течение последних нескольких месяцев, пытаясь помочь мне запустить мой прототип silverlight / f # (запущенный в RC версии VS - Ugh).Последняя проблема, которую мы пытаемся решить, - это проблема RPC.

Нам необходимо иметь возможность разбивать вызовы RPC на страницы, чтобы первая страница запрашивалась и привязывалась к сетке и отображалась, в то время как другие страницыпредварительно заполнены в фоновом режиме и объединены вместе.Я предполагаю, что код psuedo будет выглядеть так:

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

Я прошу прощения за приведенный выше код, я попытался сделать его как F #, насколько это возможно (запись в этом текстовом окне);Другим недостатком является необходимость использования обратных вызовов для привязки данных к сеткам и т. д.

Для решения этой проблемы могут быть использованы подходы к вопросу, и что является наиболее ценным?

1 Ответ

1 голос
/ 07 августа 2010

хм ... как то так? (ввод в браузере может содержать ошибки):

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

На стороне пользовательского интерфейса это будет выглядеть так (т.е. данные - ListBox или какой-либо другой элемент управления)

Loader.loadDataAsync(list => data.ItemSource = list)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...