0

Je développe une application Silverlight pour SharePoint et je souhaite obtenir des ListItems à partir d'une liste. Je sais que j'ai besoin d'interroger de manière asynchrone pour éviter de bloquer le thread de l'interface utilisateur. Normalement, j'utilise ExecuteQueryAsync mais cela ne fonctionnera pas puisque j'aime définir le résultat en tant que source DataGrid.Comment appeler une méthode de manière asynchrone dans Silverlight 4?

Comment puis-je appeler la méthode GetItemsFromList de manière asynchrone et définir le résultat en tant que source DataGrid sans générer beaucoup de surcharge de code? (Lambda?)

SharePointHelper Classe:

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; 
} 

Classe UI:

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

J'ai maintenant mis en œuvre la solution de 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(); 

Répondre

1

Je ne suis pas au courant de la classe ClientContext pour SharePoint (ou même SharePoint pour cette matière), mais je ne vois aucune méthode async dans le docs. Si cet appel est coûteux, vous pouvez envelopper l'appel dans un BackgroundWorker. BackgroundWorker exécutera la requête et vous pouvez renvoyer les résultats. Vous ne seriez pas en mesure d'affecter la Source comme vous l'avez décrit, mais plutôt de définir la Source à la fin du travail.

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; 
    } 
+0

Cela fonctionnerait mais avec cette solution j'ai besoin d'un BackgroundWorker pour chaque méthode que j'aime appeler et je dois m'inscrire à l'événement. J'ai espéré une solution plus agréable comme @Dan Wray essayé ;-) – jwillmer

+0

L'utilisation d'un rappel et la souscription à un événement sont essentiellement la même chose. Comme ces méthodes ne semblent pas être asynchrones, vous devez les rendre asynchrones. BackgroundWorker rend cela possible. Si vous n'aimez pas avoir la méthode complétée, modifiez simplement l'abonnement à: worker.RunWorkerCompleted + = (s, e) => dataGrid.Source = e.Result comme ListItemCollection; –

0

Quelque chose comme ça?

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); 
} 
+0

Obtenez cette erreur: La méthode ou la propriété appelée peut bloquer le thread d'interface utilisateur et il n'est pas autorisé. Utilisez le thread d'arrière-plan pour appeler la méthode ou la propriété, par exemple, en utilisant la méthode System.Threading.ThreadPool.QueueUserWorkItem pour appeler la méthode ou la propriété. – jwillmer

+0

Je ne connais pas du tout Sharepoint. Je suis sous l'impression que vous pouvez utiliser une méthode "ExecuteQueryAsync" quelque part pour effectuer votre requête de manière asynchrone, le code que j'ai montré ci-dessus ne montre vraiment comment vous pouvez capturer le résultat de cet appel asynchrone et le renvoyer à votre original méthode d'appel via le délégué. Si vous ne pouvez pas effectuer l'opération de manière asynchrone nativement, vous êtes probablement bloqué à l'aide d'un arrière-plan pour ce faire, comme indiqué dans la solution de Shawn. –

Questions connexes