如何在Silverlight 4中异步调用方法?

时间:2012-08-13 15:33:32

标签: silverlight sharepoint asynchronous silverlight-4.0 sharepoint-2010

我正在为SharePoint开发一个Silverlight应用程序,并希望从列表中获取ListItems。我知道我需要异步查询以避免阻塞UI线程。通常我使用ExecuteQueryAsync,但这不起作用,因为我喜欢将结果设置为DataGrid源。

如何异步调用GetItemsFromList方法并将结果设置为DataGrid源而不会产生太多代码开销? (拉姆达?)

SharePointHelper类:

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("<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>{0}</Value></Eq></Where></Query>RowLimit>4</RowLimit></View>",
                                      name);

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

    return collListItems;
}

UI类:

private void SetDataGridItemSource()
{
    dataGrid.Source = GetItemsFromList("name");
}

我现在已经实施了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(); 

2 个答案:

答案 0 :(得分:1)

我不熟悉SharePoint的ClientContext类(甚至是SharePoint),但我在docs中没有看到任何异步方法。如果此呼叫费用昂贵,您可以将呼叫包裹在BackgroundWorker中。 BackgroundWorker将执行查询,您可以返回结果。您将无法按照您的描述分配Source,而是需要在工作人员完成时设置Source。

    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("<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>{0}</Value></Eq></Where></Query>RowLimit>4</RowLimit></View>",
                                              name);

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

            args.Result = collListItems;
        }
    }

    private void WorkerOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args)
    {
        dataGrid.Source = args.Result as ListItemCollection;
    }

答案 1 :(得分:0)

这样的东西?

public delegate void ItemsLoadedCallback(IEnumerable<object> 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);
}