0

I have the following Parallel.Foreach loop to download multiple documents:

using (var ctx = new SP.ClientContext(siteURL))
            {
                ctx.Load(ctx.Web, a => a.Lists);
                ctx.ExecuteQuery();
                int i = 0;
                SP.List list = ctx.Web.Lists.GetByTitle("ArchivedData");
                SP.ListItemCollectionPosition position = null;
                int rowLimit = 100;
                var camlQuery = new SP.CamlQuery();
                camlQuery.ViewXml = @"<View Scope='RecursiveAll'>
                                      <Query>
                                        <OrderBy Override='TRUE'><FieldRef Name='ID'/></OrderBy>
                                      </Query>
                                      <ViewFields>
                                            <FieldRef Name='Title'/><FieldRef Name='ID' />
                                      </ViewFields>
                                      <RowLimit Page='TRUE'>" + rowLimit + "</RowLimit></View>";
                do
                {
                    SP.ListItemCollection listItems = null;
                    camlQuery.ListItemCollectionPosition = position;
                    listItems = list.GetItems(camlQuery);
                    ctx.Load(listItems);
                    ctx.ExecuteQuery();
                    i += 100;
                    position = listItems.ListItemCollectionPosition;    
Parallel.ForEach(listItems,
                        () => CreateClientContext(siteURL),
                        (currentfileItem, localContext) =>
                        {
                            ctx.Load(currentfileItem, x => x.File);
                            ctx.ExecuteQuery();
                            var fileRef = currentfileItem.File.ServerRelativeUrl;
                            var fileInfo = SP.File.OpenBinaryDirect(ctx, fileRef);
                            var fileName = @"c:\downloads\" + currentfileItem.File.Name;
                            using (var fileStream = System.IO.File.Create(fileName))
                            {
                                fileInfo.Stream.CopyTo(fileStream);
                                //Generate MD5 HASH
                              ... 

                                    //Record HASH and File name in db with file name and title if there, and SharePointID
                             ...
                            //Remove the file we don't need it anymore
                            ...
                           }
                        });


items.AddRange(listItems.ToList());
                    Console.WriteLine(i);
                }
                while (position != null);

Here is the CreateClientContext method I got from another article:

  private static ClientContext CreateClientContext(string url)
    {
        ClientContext context = new ClientContext(url);
        return context;
    }

I know I need this for the parallel foreach since it is not threadsafe. But when I put in this code I get the following compiler error:

Cannot convert lambda expression to type 'System.Threading.Tasks.ParallelOptions' because it is not a delegate type

So I am trying to find out which overload to use and I cannot seem to figure this out. I know the error is stating that my lambda is being used in the place for ParallelOptions, but I can't figure out the error.

1 Answer 1

0

The compiler seems to think you are using the wrong signature for your Parallel.ForEach call. Unfortunately, you do not give us the full call so I can't see which overload you are using.

A link for all overloads: Parellel.ForEach official documentation

On another note, I'd tend to advise to run asynchronous query instead of your parallel call. It would spare some resources and if it is not your process that takes teams but the actual SP call, it would have the same performance.

ClientContext.ExecuteQueryAsync Method - Official documentation

2
  • Edited for full call code
    – john
    Commented May 18, 2018 at 14:30
  • Your full call seems to rely on a potential overload Parallel.ForEach(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoop>) but I can't seem to find it. Please refer to the official documentation to try and get a potential overload. Parallel.ForEach Documentation Commented May 22, 2018 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.