这件事很少见,但它已经出现过好几次了。这一次,下载文件的请求被卡住了,我们的软件已经挂了将近17个小时了。我们使用了一个ProcDump,它显示了在"Socket.Receive“调用过程中发生了延迟,这是Microsoft.SharePoint.Client.ClientContext.ExecuteQuery调用的结果。
下面是ProcDump堆栈跟踪:
ChildEBP RetAddr Caller, Callee
08a5de44 6f45a7b5 mswsock!SockWaitForSingleObject+0x125, calling ntdll_77a80000!NtWaitForSingleObject
08a5dea0 6f46c7a8 mswsock!WSPRecv+0x2e8, calling mswsock!SockWaitForSingleObject
08a5df14 75681560 ws2_32!recv+0x100
08a5df68 72bccbff (MethodDesc 729f4eb4 +0x3b DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags))
08a5df90 72bccbff (MethodDesc 729f4eb4 +0x3b DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags))
08a5dfac 72b6c3dd (MethodDesc 729e2b04 +0xbd System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags, System.Net.Sockets.SocketError ByRef)), calling 72aed3fc
08a5dfd4 72b6c2ce (MethodDesc 729e2af8 +0x1e System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags)), calling (MethodDesc 729e2b04 +0 System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags, System.Net.Sockets.SocketError ByRef))
08a5dffc 72b6c203 (MethodDesc 729e0590 +0x83 System.Net.Sockets.NetworkStream.Read(Byte[], Int32, Int32)), calling (MethodDesc 729e2af8 +0 System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags))
08a5e030 72b5335d (MethodDesc 729e0ad0 +0x21 System.Net.FixedSizeReader.ReadPacket(Byte[], Int32, Int32))
08a5e04c 72b9b65e (MethodDesc 72a3fcb8 +0xa2 System.Net.Security._SslStream.StartFrameBody(Int32, Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)), calling (MethodDesc 729e0ad0 +0 System.Net.FixedSizeReader.ReadPacket(Byte[], Int32, Int32))
08a5e06c 72b9b3ba (MethodDesc 72a3fcac +0x92 System.Net.Security._SslStream.StartFrameHeader(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)), calling (MethodDesc 72a3fcb8 +0 System.Net.Security._SslStream.StartFrameBody(Int32, Byte[], Int32, Int32, System.Net.AsyncProtocolRequest))
08a5e094 72b9b087 (MethodDesc 72a3fca0 +0x77 System.Net.Security._SslStream.StartReading(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)), calling (MethodDesc 72a3fcac +0 System.Net.Security._SslStream.StartFrameHeader(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest))
08a5e0bc 72b9af60 (MethodDesc 729e0374 +0xc8 System.Net.Security._SslStream.ProcessRead(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)), calling (MethodDesc 72a3fca0 +0 System.Net.Security._SslStream.StartReading(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest))
08a5e0fc 72b532f3 (MethodDesc 72a4170c +0x4f System.Net.TlsStream.Read(Byte[], Int32, Int32)), calling (MethodDesc 729e0374 +0 System.Net.Security._SslStream.ProcessRead(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest))
08a5e12c 72b6c0d0 (MethodDesc 72a3d738 +0x68 System.Net.PooledStream.Read(Byte[], Int32, Int32))
08a5e164 73216b6c (MethodDesc 72a3aa78 System.Net.ChunkParser.HandlePayload())
08a5e188 72b8ec41 (MethodDesc 729db7ec +0x3d System.Net.ChunkParser.ProcessResponse()), calling (MethodDesc 72a3aa78 +0 System.Net.ChunkParser.HandlePayload())
08a5e19c 730428a7 (MethodDesc 72a3aa24 +0x2f System.Net.ChunkParser.Read(Byte[], Int32, Int32)), calling (MethodDesc 729db7ec +0 System.Net.ChunkParser.ProcessResponse())
08a5e1c0 7320b446 (MethodDesc 72a3ee4c System.Net.ConnectStream.ReadWithoutValidation(Byte[], Int32, Int32, Boolean)), calling (MethodDesc 72a3aa24 +0 System.Net.ChunkParser.Read(Byte[], Int32, Int32))
08a5e1f4 72b6d885 (MethodDesc 729dff68 +0xe5 System.Net.ConnectStream.Read(Byte[], Int32, Int32)), calling (MethodDesc 72a3ee4c +0 System.Net.ConnectStream.ReadWithoutValidation(Byte[], Int32, Int32, Boolean))
08a5e230 013b8087 (MethodDesc 013849a0 +0xb7 Microsoft.SharePoint.Client.Mime.BufferedReadStream.Read(Byte[], Int32, Int32))
08a5e250 013b7eb2 (MethodDesc 0826e348 +0x2a Microsoft.SharePoint.Client.Mime.DelimitedStreamReader.Read(DelimitedReadStream, Byte[], Int32, Int32))
08a5e26c 013b7d08 (MethodDesc 0826e6a0 +0x48 Microsoft.SharePoint.Client.Mime.DelimitedStreamReader+DelimitedReadStream.Read(Byte[], Int32, Int32)), calling (MethodDesc 0826e348 +0 Microsoft.SharePoint.Client.Mime.DelimitedStreamReader.Read(DelimitedReadStream, Byte[], Int32, Int32))
08a5e28c 013b9c95 (MethodDesc 08d5ef3c +0x45 Microsoft.SharePoint.Client.ChunkStreamBuilder.CopyFrom(System.IO.Stream))
08a5e2a8 096da950 (MethodDesc 08d5abf8 +0x2a0 Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()), calling (MethodDesc 08d5ef3c +0 Microsoft.SharePoint.Client.ChunkStreamBuilder.CopyFrom(System.IO.Stream))
08a5e2f8 096da228 (MethodDesc 08d5ac1c +0xc8 Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(Microsoft.SharePoint.Client.ChunkStringBuilder)), calling (MethodDesc 08d5abf8 +0 Microsoft.SharePoint.Client.ClientRequest.ProcessResponse())
08a5e324 08d4cf9d (MethodDesc 08d5956c +0x18d Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()), calling (MethodDesc 08d5ac1c +0 Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(Microsoft.SharePoint.Client.ChunkStringBuilder))
...our code which calls Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()我们能用这个做点什么吗?或者我们应该依靠微软在他们的CSOM库中解决这个问题?
注意事项:我们使用Microsoft.SharePointOnline.CSOM库(https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM/16.1.19927.12000)的16.1.19927.12000版本。
RequestTimeout没有显式设置,因此它应该使用默认值(3分钟)。我们通常会时不时地看到超时,这是正常的。但我们不希望看到一个永远挂着的请求。
编辑:
我有一些关于这个问题的最新情况。上一次,我们并没有停止这一进程,而是决定等待。经过32.5小时的等待,代码最终得到了一个IOException,我们能够完成这个过程。
IOException:无法从传输连接读取数据:现有连接被远程主机强制关闭。
我们使用的是.NET 4.6.1。
发布于 2021-09-05 19:06:22
如果没有任何代码示例,我将不得不做一些用法假设。如果您使用它的方式与此类似,我们至少可以使用取消令牌从摊位中挣脱出来。然后,你可以在你认为合适的情况下处理它。它可能就像重试一样简单,但是如果不调试行为,就很难说了。
try
{
var cancelToken = new CancellationTokenSource();
var ms = 600_000;
cancelToken.CancelAfter(ms);
await ExecuteQueryWithTimeout(cancelToken);
}
catch (TaskCanceledException)
{
Console.WriteLine("Tasks cancelled: timed out");
}
finally
{
cancelToken.Dispose();
}ExecuteQuery的异步方法
private static async Task ExecuteQueryWithTimeout(CancellationToken token)
{
await Task.Run(()=> {
Uri uri = new Uri(folderUrl);
SP.Folder folder = web.GetFolderByServerRelativeUrl(uri.AbsolutePath);
context.Load(folder);
context.ExecuteQuery();
});
}发布于 2021-09-06 04:07:24
我能想到几个原因:-
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
发布于 2021-09-10 20:05:51
最近,我通过CSOM方法在SharePoint中递归地抛出文件夹和子文件夹(超过9000多个文件),在一个查询中我遇到了这个问题,经过长期的研究,我遇到了这个Microsoft文档,并解释了如何解决这个问题:避免在SharePoint Online中被节流或阻塞。
我使用Microsoft Docs文章建议的扩展方法提取下面的代码。
public static class CsomExtensions
{
public static void ExecuteQueryWithIncrementalRetry(this ClientContext clientContext, int retryCount, int delay)
{
int retryAttempts = 0;
int backoffInterval = delay;
int retryAfterInterval = 0;
bool retry = false;
ClientRequestWrapper wrapper = null;
if (retryCount <= 0)
throw new ArgumentException("Provide a retry count greater than zero.");
if (delay <= 0)
throw new ArgumentException("Provide a delay greater than zero.");
// Do while retry attempt is less than retry count
while (retryAttempts < retryCount)
{
try
{
if (!retry)
{
clientContext.ExecuteQuery();
return;
}
else
{
//increment the retry count
retryAttempts++;
// retry the previous request using wrapper
if (wrapper != null && wrapper.Value != null)
{
clientContext.RetryQuery(wrapper.Value);
return;
}
// retry the previous request as normal
else
{
clientContext.ExecuteQuery();
return;
}
}
}
catch (WebException ex)
{
var response = ex.Response as HttpWebResponse;
// Check if request was throttled - http status code 429
// Check is request failed due to server unavailable - http status code 503
if (response != null && (response.StatusCode == (HttpStatusCode)429 || response.StatusCode == (HttpStatusCode)503))
{
wrapper = (ClientRequestWrapper)ex.Data["ClientRequest"];
retry = true;
// Determine the retry after value - use the `Retry-After` header when available
string retryAfterHeader = response.GetResponseHeader("Retry-After");
if (!string.IsNullOrEmpty(retryAfterHeader))
{
if (!Int32.TryParse(retryAfterHeader, out retryAfterInterval))
{
retryAfterInterval = backoffInterval;
}
}
else
{
retryAfterInterval = backoffInterval;
}
// Delay for the requested seconds
Thread.Sleep(retryAfterInterval * 1000);
// Increase counters
backoffInterval = backoffInterval * 2;
}
else
{
throw;
}
}
}
throw new MaximumRetryAttemptedException($"Maximum retry attempts {retryCount}, has be attempted.");
}
}
[Serializable]
public class MaximumRetryAttemptedException : Exception
{
public MaximumRetryAttemptedException(string message) : base(message) { }
}https://stackoverflow.com/questions/68865287
复制相似问题