Tuesday, August 14, 2012

How to call a methode asynchronous in Silverlight 4?

How to call a methode asynchronous in Silverlight 4?
I'm developing a Silverlight app for SharePoint and want to get ListItems from a list. I know I need to query async to avoid blocking the ui thread. Normaly I use ExecuteQueryAsync but that won't work since i like to set the result as DataGrid source. How can I call the GetItemsFromList methode async and set the result as DataGrid source without creating much code overhead? (lambda?)
SharePointHelper Class:
public static ListItemCollection GetItemsFromList(string name)
{
    var context = ClientContext.Current;
    var targetList = context.Web.Lists.GetByTitle("ListName");

    CamlQuery camlQuery = new CamlQuery();
    camlQuery.ViewXml = string.Format("<Where>{0}</Where>RowLimit>4</RowLimit>",
                                      name);

    ListItemCollection collListItems = targetList.GetItems(camlQuery);
    context.ExecuteQuery();

    return collListItems;
}
UI Class:
private void SetDataGridItemSource()
{
    dataGrid.Source = GetItemsFromList("name");
}
I have now implemented the solution from Shawn Kendrot:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (sender, args) => 
{
    args.Result = SharePointHelpers.GetItemsFromList("name");
};
worker.RunWorkerCompleted += (s, e) => dataSource.Source = e.Result as ListItemCollection;
worker.RunWorkerAsync(); 
Answers & Comments...

Answer: 1Something like this?
public delegate void ItemsLoadedCallback(IEnumerable Entities);
public static void GetItemsFromList(string name, ItemsLoadedCallback Callback)
{
    // codesnip

    // Do async thing, on return call:
    if (Callback != null)
    {
        Callback(collListItems);
    }
}


private void SetDataGridItemSource()
{
    GetItemsFromList("name", (items) => dataGrid.Source = items);
}
Answer by Dan Wray for How to call a methode asynchronous in Silverlight 4?

Answer: 2I'm not familiar with the ClientContext class for SharePoint (or even SharePoint for that matter), but I do not see any async methods in the docs. If this call is going to be expensive, you can wrap the call in a BackgroundWorker. The BackgroundWorker would execute the query and you can return the results. You would not be able to assign the Source as you have described, but instead would need to set the Source when the worker completes.
    private void SetDataGridItemSource()
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += WorkerOnDoWork;
        worker.RunWorkerCompleted += WorkerOnRunWorkerCompleted;
        worker.RunWorkerAsync("name");       
    }

    private void WorkerOnDoWork(object sender, DoWorkEventArgs args)
    {
        if(args.Argument != null)
        {
            string name = args.Argument.ToString();
            var context = ClientContext.Current;
            var targetList = context.Web.Lists.GetByTitle("ListName");

            CamlQuery camlQuery = new CamlQuery();
            camlQuery.ViewXml = string.Format("<Where>{0}</Where>RowLimit>4</RowLimit>",
                                              name);

            ListItemCollection collListItems = targetList.GetItems(camlQuery);
            context.ExecuteQuery();

            args.Result = collListItems;
        }
    }

    private void WorkerOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args)
    {
        dataGrid.Source = args.Result as ListItemCollection;
    }
Answer by Shawn Kendrot for How to call a methode asynchronous in Silverlight 4?

No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog