[英]Error on System.Linq.Enumerable.<TakeIterator>d__3a`1.MoveNext()
I have the following code to iterate over subwebs of a sharepoint site. 我有以下代码来迭代sharepoint站点的子站点。 If I debug it line by line, it never goes to my catchs.
如果我逐行调试它,它永远不会被我的捕获。
however on the uls logs I have this exception which I dont know what it means or if I should worry 但是在uls日志中,我有这个例外,我不知道这意味着什么,或者我应该担心
53b416d1-1497-4b40-beb5-cd261180ece8 Stack trace:
at Microsoft.SharePoint.SPWeb.get_Created()
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.<>c__DisplayClass8.<LoadGridData>b__7(SPWeb d)
at System.Linq.EnumerableSorter`2.ComputeKeys(TElement[] elements, Int32 count)
at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
at System.Linq.Enumerable.<TakeIterator>d__3a`1.MoveNext()
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.<>c__DisplayClass8.<LoadGridData>b__5()
at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass5.<RunWithElevatedPrivileges>b__3()
at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param)
at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode)
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.LoadGridData()
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.OnPreRender(EventArgs e)
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at Microsoft.SharePoint.Publishing.TemplateRedirectionPage.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at System.Web.HttpApplication.PipelineStepManager.ResumeSteps(Exception error)
at System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb)
at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
My code is as follows 我的代码如下
private void LoadGridData()
{
try
{
String currentUrl = SPContext.Current.Site.Url;
var jobInfoList = new List<JobInfo>();
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (var clientSiteCollection = new SPSite(currentUrl))
{
foreach (
SPWeb web in
clientSiteCollection.AllWebs.AsSafeEnumerable().Where(
c =>
c.AllProperties[Constants.WebProperties.General.WebTemplate] != null &&
c.AllProperties[Constants.WebProperties.General.WebTemplate].ToString() ==
Constants.WebTemplates.JobWebPropertyName).OrderByDescending(d => d.Created).Take(5)
)
{
if (web.DoesUserHavePermissions(SPContext.Current.Web.CurrentUser.LoginName,
SPBasePermissions.Open))
{
SPList jobInfoListSp = web.Lists.TryGetList(Constants.Lists.JobInfoName);
if (jobInfoListSp != null)
{
if (jobInfoListSp.Items.Count > 0)
{
var value =
new SPFieldUrlValue(
jobInfoListSp.Items[0][Constants.FieldNames.Job.iPowerLink].ToString());
jobInfoList.Add(new JobInfo
{
JobName =
jobInfoListSp.Items[0][Constants.FieldNames.Job.JobName].ToString(),
JobCode =
jobInfoListSp.Items[0][Constants.FieldNames.Job.JobCode].ToString(),
IPowerLink = value.Url,
JobWebsite = web.Url,
IsConfidential =
HelperFunctions.ConvertToBoolean(
jobInfoListSp.Items[0][Constants.FieldNames.Job.Confidential]
.ToString())
});
}
}
}
web.Dispose();
}
}
});
_lastCreatedJobsGrid.DataSource = jobInfoList;
_lastCreatedJobsGrid.DataBind();
}
catch (Exception ex)
{
LoggingService.LogError(LoggingCategory.Job, ex);
}
}
public static class SPWebCollectionExtensions
{
public static IEnumerable<SPWeb> AsSafeEnumerable(this SPWebCollection webs)
{
foreach (SPWeb web in webs)
{
try
{
yield return web;
}
finally
{
web.Dispose();
}
}
}
}
Any idea what could be the cause and solution if needed? 如果需要,任何想法可能是什么原因和解决方案?
Update: 更新:
I made the query on a variable first, and then the foreach, I also removed the AsSafeEnumerable I wonder if I will have memoryleaks with this change? 我首先对变量进行了查询,然后是foreach,我还删除了AsSafeEnumerable,我想知道我是否会对此更改进行内存泄漏?
Update 2: When trying to use the code in the first answer which is impressive, I still get disposing problems. 更新2:当尝试在第一个答案中使用令人印象深刻的代码时,我仍然处理问题。
An 一个
SPRequest object was not disposed before the end of this thread. To avoid wasting system resources, dispose of this object or its parent (such as an SPSite or SPWeb) as soon as you are done using it. This object will now be disposed. Allocation Id: {96F3F1CB-DBD1-4514-AB9A-D49424AB0B6A} This SPRequest was allocated
at
at Microsoft.SharePoint.Library.SPRequest..ctor()
at Microsoft.SharePoint.SPGlobal.CreateSPRequestAndSetIdentity(SPSite site, String name, Boolean bNotGlobalAdminCode, String strUrl, Boolean bNotAddToContext, Byte[] UserToken, SPAppPrincipalToken appPrincipalToken, String userName, Boolean bIgnoreTokenTimeout, Boolean bAsAnonymous)
at Microsoft.SharePoint.SPWeb.InitializeSPRequest()
at Microsoft.SharePoint.SPWeb.EnsureSPRequest()
at Microsoft.SharePoint.SPWeb.get_AllProperties()
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.<>c__DisplayClass8.<LoadGridData>b__6(SPWeb c)
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
at xx.SP.DMS.WebParts.Extensions.Safe.<SafeTake>d__0`1.MoveNext()
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.<>c__DisplayClass8.<LoadGridData>b__5()
at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass5.<RunWithElevatedPrivileges>b__3()
at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param)
at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode)
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.LoadGridData()
at xx.SP.DMS.WebParts.WebParts.LastCreatedJobs.LastCreatedJobs.OnPreRender(EventArgs e)
I believe the problem is the SPWeb
is getting disposed after invoking the Enumerable.OrderByDescending
. 我相信问题是在调用
Enumerable.OrderByDescending
后SPWeb
正在被处理掉。 This linq method is not lazy evaluated, so the finally
block inside AsSafeEnumerable
will get triggered. 这个linq方法不是惰性求值,因此
AsSafeEnumerable
的finally
块将被触发。
Sample: 样品:
public class Disposed : IDisposable
{
public bool IsDisposed { get; private set; }
public DateTime? Created { get; set; }
public void Dispose()
{
Console.WriteLine("Disposed");
IsDisposed = true;
}
}
public IEnumerable<Disposed> GetDisposed()
{
Func<Disposed> factory = () => new Disposed { Created = DateTime.Now };
foreach(var f in Enumerable.Repeat(factory, 5))
{
Console.WriteLine("In Enumerable");
var item = f();
try
{
Console.WriteLine("Returning item");
yield return item;
}
finally
{
item.Dispose();
}
Console.WriteLine("Next iteration.");
}
}
Usage 1: 用法1:
foreach(var item in GetDisposed().Take(5))
{
Console.WriteLine(item.IsDisposed);
}
In Enumerable
Returning item
False
Disposed
Next iteration.
In Enumerable
Returning item
False
Disposed
Next iteration.
In Enumerable
Returning item
False
Disposed
Next iteration.
In Enumerable
Returning item
False
Disposed
Next iteration.
In Enumerable
Returning item
False
Disposed
Usage 2: 用法2:
foreach(var item in GetDisposed().OrderByDescending(x => x.Created).Take(5))
{
Console.WriteLine(item.IsDisposed);
}
Log: 日志:
In Enumerable
Returning item
Disposed
Next iteration.
In Enumerable
Returning item
Disposed
Next iteration.
In Enumerable
Returning item
Disposed
Next iteration.
In Enumerable
Returning item
Disposed
Next iteration.
In Enumerable
Returning item
Disposed
Next iteration.
True
True
True
True
True
Edit: 编辑:
Here is an extension method to safely dispose objects not taken: 这是一种安全地处理未采取的对象的扩展方法:
public static IEnumerable<TSource> SafeTake<TSource>(
this IEnumerable<TSource> source,
int count
) where TSource : IDisposable
{
foreach(var item in source)
{
if(--count >= 0)
{
yield return item;
}
else if (item != null)
{
item.Dispose();
}
}
}
public static IEnumerable<TSource> SafeWhere<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
) where TSource: IDisposable
{
return source.SelectMany(x => {
var result = predicate(x);
if(!result && x != null) x.Dispose();
return Enumerable.Repeat(x, result ? 1 : 0);
});
}
Usage: 用法:
foreach (
SPWeb web in
clientSiteCollection.AllWebs.SafeWhere(
c =>
c.AllProperties[Constants.WebProperties.General.WebTemplate] != null &&
c.AllProperties[Constants.WebProperties.General.WebTemplate].ToString() ==
Constants.WebTemplates.JobWebPropertyName).OrderByDescending(d => d.Created).SafeTake(5)
)
{
try
{
if (!web.DoesUserHavePermissions(SPContext.Current.Web.CurrentUser.LoginName, SPBasePermissions.Open)) continue;
SPList jobInfoListSp = web.Lists.TryGetList(Constants.Lists.JobInfoName);
if (jobInfoListSp == null) continue;
if (0 >= jobInfoListSp.Items.Count) continue;
var value =
new SPFieldUrlValue(
jobInfoListSp.Items[0][Constants.FieldNames.Job.iPowerLink].ToString());
jobInfoList.Add(new JobInfo
{
JobName =
jobInfoListSp.Items[0][Constants.FieldNames.Job.JobName].ToString(),
JobCode =
jobInfoListSp.Items[0][Constants.FieldNames.Job.JobCode].ToString(),
IPowerLink = value.Url,
JobWebsite = web.Url,
IsConfidential =
HelperFunctions.ConvertToBoolean(
jobInfoListSp.Items[0][Constants.FieldNames.Job.Confidential]
.ToString())
});
}
finally
{
web.Dispose();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.