SharePoint“正在中止线程”循环通过SPListItemCollection

时间:2009-11-05 18:06:28

标签: sharepoint moss sharepoint-2007

我有一个包含~500项的SPListItemCollection。我循环使用for for each循环,每次抓取文件并将其写入pdf文档。我收到错误“线程被中止”。它看起来是一个超时问题,但我不知道如何解决它? 200-300项的收藏品很好。有什么方法可以阻止这个错误。如果我无法增加超时,我将需要批量处理。

更新

我尝试将100个项目分批处理。每个新的100项使用新的spweb和站点并从sharepoint中提取项目。这都是在同一个方法中完成的(所以我没有重新创建我的自定义对象)但是仍然出现相同的错误......

5 个答案:

答案 0 :(得分:3)

http://blogs.msdn.com/solutions/archive/2009/01/08/getting-around-thread-was-being-aborted-error-when-creating-ep-site.aspx

  1. 在记事本等基本文本编辑器中,打开web.config文件,例如“%SYSTEMDRIVE%\Inetpub\wwwroot -要么- %SYSTEMDRIVE%\\Inetpub\wwwroot\wss\VirtualDirectories\80 folder

  2. 按CTRL + F打开“查找”对话框。

  3. 找到以下标记:

    <httpRuntime maxRequestLength="51200" />

  4. 将其替换为此标记:

    <httpRuntime executionTimeout="6000" maxRequestLength="51200" />

  5. 这似乎让它对我有用。

答案 1 :(得分:1)

请记住,迭代列表项有一种正确和非常错误的方法,它会对性能产生巨大影响。错误的方法会导致对数据库进行n + 1次调用以获取列表数据;正确的方式只能对数据库进行一次调用。

最差:

for (int i = 0; i < myList.Items.Count; i++)
{
  SPListItem thisItem = myList.Items[i];

  // yada yada yada
}

为:

foreach (SPListItem item in myList.Items)
{
  // yada yada yada
}

右:

SPListItemCollection myItems = myList.Items;
foreach (SPListItem item in myItems)
{
  // yada yada yada
}

已更新:要反映更准确的指导

答案 2 :(得分:0)

迭代SPListItemCollection绝不是一个好主意(但遗憾的是有时候唯一的方法)。您可以考虑在LongRunningOperation中包装此代码。这是我自己改编的一些代码:

实际课程:

using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.SharePoint;

namespace Common.LongRunningJobs
{
  /// <summary>
  /// Provides a long running job wrapper around converting multiple files
  /// </summary>
  [CLSCompliant(false)]
  public class FileToPdfLongRunningJob : LongRunningOperationJob
  {
    private List<string> fileUrls;

    /// <summary>
    /// Initializes a new instance of the <see cref="FileToPdfLongRunningJob"/> class.
    /// </summary>
    /// <param name="urls">The urls of the files to create pdfs from.</param>
    public FileToPdfLongRunningJob(List<string> urls)
    {
      fileUrls = urls;
    }

    /// <summary>
    /// Does the actual work of converting the files, while providing the user with status updates.
    /// </summary>
    public override void DoWork()
    {
      try
      {
        using (var currentWeb = Site.OpenWeb(parentWeb))
        {
          OperationsPerformed = 0;

          foreach (var url in fileUrls)
          {
            SPFile file = currentWeb.GetFile(url);

            // DO PDF OUTPUT

            StatusDescription = string.Format(CultureInfo.InvariantCulture, "busy converting {0} van {1}, file: {2}...", (OperationsPerformed + 1), TotalOperationsToBePerformed, file.Name);
            UpdateStatus();

            OperationsPerformed++;
          }
        }
      }
      catch (Exception ex)
      {
        // LOG ERROR
      }
    }
  }
}

使用上述类别:

private void ConvertFiles()
{
  const string PROGRESS_PAGE_URL = "/_layouts/LongRunningOperationProgress.aspx";
  var urls = new List<string>();
  foreach (SPListItem item in yourlistitemcollection)
  {
    urls.Add(item.File.Url);
  }
  var longRunningJob = new FileMoveLongRunningJob(urls)
  {
    Title = "Pdf conversion Long Running Job",
    TotalOperationsToBePerformed = urls.Count,
    RedirectWhenFinished = true,
    NavigateWhenDoneUrl = urlToRedirectTo;//i.e. SPContext.GetContext(Context).List.RootFolder.ServerRelativeUrl
  };

  longRunningJob.Start(SPContext.Current.Web);
  string url = string.Format("{0}{1}?JobId={2}", SPContext.Current.Web.Url, PROGRESS_PAGE_URL, longRunningJob.JobId);
  SPUtility.Redirect(url, SPRedirectFlags.Default, Context);
}

答案 3 :(得分:0)

尝试在获取项目之前创建新的SPSite和SPWeb对象(并从新的Web获取它们)。

通常可以解决问题。

答案 4 :(得分:0)

迭代列表的代码中可能存在潜在的陷阱。如果您可以在此处粘贴代码,那将是一件好事。 此外,最好使用Caml查询列表项,并仅选择操作所需的字段而不是全部。