首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SharePoint CSOM请求挂起

SharePoint CSOM请求挂起
EN

Stack Overflow用户
提问于 2021-08-20 16:22:57
回答 3查看 667关注 0票数 0

这件事很少见,但它已经出现过好几次了。这一次,下载文件的请求被卡住了,我们的软件已经挂了将近17个小时了。我们使用了一个ProcDump,它显示了在"Socket.Receive“调用过程中发生了延迟,这是Microsoft.SharePoint.Client.ClientContext.ExecuteQuery调用的结果。

下面是ProcDump堆栈跟踪:

代码语言:javascript
复制
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,我们能够完成这个过程。

  • 下载文件请求在2021-08-25 16:29:33.6426877发送.
  • 代码在"System.Net.Sockets.Socket.Receive“行中停留了32.5小时。
  • 在2021-08-27 01:11:23.5161189引发了一个异常。

IOException:无法从传输连接读取数据:现有连接被远程主机强制关闭。

我们使用的是.NET 4.6.1。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-09-05 19:06:22

如果没有任何代码示例,我将不得不做一些用法假设。如果您使用它的方式与此类似,我们至少可以使用取消令牌从摊位中挣脱出来。然后,你可以在你认为合适的情况下处理它。它可能就像重试一样简单,但是如果不调试行为,就很难说了。

代码语言:javascript
复制
    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的异步方法

代码语言:javascript
复制
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();
    });
}
票数 1
EN

Stack Overflow用户

发布于 2021-09-06 04:07:24

我能想到几个原因:-

  1. 连接正在TLS 1.0上进行。尝试安装OS更新,更新.NET框架,通过显式设置使连接在TLS1.2上。参考文献:https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

  1. 检查防火墙规则,以确保它们没有阻塞连接
票数 1
EN

Stack Overflow用户

发布于 2021-09-10 20:05:51

最近,我通过CSOM方法在SharePoint中递归地抛出文件夹和子文件夹(超过9000多个文件),在一个查询中我遇到了这个问题,经过长期的研究,我遇到了这个Microsoft文档,并解释了如何解决这个问题:避免在SharePoint Online中被节流或阻塞

我使用Microsoft Docs文章建议的扩展方法提取下面的代码。

代码语言:javascript
复制
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) { }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68865287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档