我有一个foreach循环,效果很好。但我想实施TPL,所以做了以下事情:
Parallel.ForEach(fileList, currentfileItem =>
{
_clientContext.Load(currentfileItem, w => w.File);
_clientContext.ExecuteQuery();
if (currentfileItem.File == null)
{
throw new Exception(
String.Format("File information not found for the item {0}",
currentfileItem.DisplayName));
}
var currentFileName = currentfileItem.File.Name;
if (!string.IsNullOrEmpty(docRevVersionId))
{
var info = Microsoft.SharePoint.Client.File.OpenBinaryDirect(
_clientContext, currentfileItem["fRef"].ToString());
if (info != null)
{
UpdateToServer(Id, currentFileName, info.Stream);
}
}
});
一旦我实施了TPL,我就会得到StackOverflow Exception
。我很确定这是因为TPL,因为没有TPL,应用程序运行正常。
fileList
是IEnumerable<ListItem>
修改
SOE可能是这样的:(VS内存不足以存储异常)
并更新了代码:
Parallel.ForEach(fileList,
() => CreateClientContext(ConfigurationDetails.SharePointUri), //This function creates a new context for the specified url.
(currentfileItem, loopState, localContext) =>
{
_clientContext.Load(currentfileItem, w => w.File);
_clientContext.ExecuteQuery();
if (currentfileItem.File == null)
{
throw new Exception(String.Format("File information not found for the item {0}", currentfileItem.DisplayName));
}
var currentFileName = currentfileItem.File.Name;
if (!string.IsNullOrEmpty(docRevVersionId))
{
var info = Microsoft.SharePoint.Client.File.OpenBinaryDirect(_clientContext, currentfileItem["fRef"].ToString());
if (info != null)
{
UpdateToServer(Id, currentFileName, info.Stream);
}
}
},localContext => localContext.Dispose());
private static ClientContext CreateClientContext(string URI)
{
ClientContext context = new ClientContext(URI);
//...Magic...
return context;
}
答案 0 :(得分:4)
ClientContext不是线程安全的,因此每个线程需要一个实例。 Parallel.ForEach
内置了创建线程本地对象的方法,因此您不需要在每次循环迭代时创建它,只需要生成每个线程。
Parallel.ForEach(fileList,
() => CreateClientContext(storeUrl), //This function creates a new context for the specified url.
(currentfileItem, loopState, localContext) =>
{
localContext.Load(currentfileItem, w => w.File);
localContext.ExecuteQuery();
if (currentfileItem.File == null)
{
throw new Exception(
String.Format("File information not found for the item {0}",
currentfileItem.DisplayName));
}
var currentFileName = currentfileItem.File.Name;
if (!string.IsNullOrEmpty(docRevVersionId))
{
var info = Microsoft.SharePoint.Client.File.OpenBinaryDirect(
localContext, currentfileItem["fRef"].ToString());
if (info != null)
{
UpdateToServer(Id, currentFileName, info.Stream);
}
}
return localContext;
},
(localContext) => localContext.Dispose()); //Dispose the thread local context
//Elsewhere
private static ClientContext CreateClientContext(string url)
{
ClientContext context = new ClientContext(url);
//Perform any additional setup you need on the context here.
//If you don't need any you could just replace "CreateClientContext(storeUrl)"
//with "new ClientContext(storeUrl)" up at the ForEach declaration.
return context;
}
您可能希望查看UpdateToServer
并检查它是否也是线程安全的。