gpt4 book ai didi

c# - 使用 SocketAsyncEventArgs 时是否可以删除 ExecutionContext 和 Thread 分配?

转载 作者:IT王子 更新时间:2023-10-29 04:13:15 32 4
gpt4 key购买 nike

如果您分析一个使用 SocketAsyncEventArgs 的简单客户端应用程序,您会注意到 ThreadExecutionContext 分配。

分配的来源是 SocketAsyncEventArgs.StartOperationCommon,它使用 ExecutionContext.CreateCopy() 创建 ExecutionContext 的副本。

ExecutionContext.SuppressFlow 似乎是抑制此分配的好方法。但是,此方法本身会在新线程中运行时生成分配。

如何避免这些分配?

最佳答案

  1. SocketAsyncEventArgs

    public class SocketAsyncEventArgs : EventArgs, IDisposable {
    //...
    // Method called to prepare for a native async socket call.
    // This method performs the tasks common to all socket operations.
    internal void StartOperationCommon(Socket socket) {

    //...

    // Prepare execution context for callback.

    if (ExecutionContext.IsFlowSuppressed()) {
    // This condition is what you need to pass.

    // Fast path for when flow is suppressed.

    m_Context = null;
    m_ContextCopy = null;

    } else {

    // Flow is not suppressed.

    //...

    // If there is an execution context we need
    //a fresh copy for each completion.

    if(m_Context != null) {
    m_ContextCopy = m_Context.CreateCopy();
    }
    }

    // Remember current socket.
    m_CurrentSocket = socket;
    }




    [Pure]
    public static bool IsFlowSuppressed()
    {
    return Thread.CurrentThread.GetExecutionContextReader().IsFlowSuppressed;
    }
    //...
    }
  2. 执行上下文

    [Serializable] 
    public sealed class ExecutionContext : IDisposable, ISerializable
    {
    //...
    // Misc state variables.
    private ExecutionContext m_Context;
    private ExecutionContext m_ContextCopy;
    private ContextCallback m_ExecutionCallback;
    //...

    internal struct Reader
    {
    ExecutionContext m_ec;
    //...
    public bool IsFlowSuppressed
    {
    #if !FEATURE_CORECLR
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    #endif
    get { return IsNull ? false : m_ec.isFlowSuppressed; }
    }

    } //end of Reader


    internal bool isFlowSuppressed
    {
    get
    {
    return (_flags & Flags.IsFlowSuppressed) != Flags.None;
    }
    set
    {
    Contract.Assert(!IsPreAllocatedDefault);
    if (value)
    _flags |= Flags.IsFlowSuppressed;
    else
    _flags &= ~Flags.IsFlowSuppressed;
    }
    }


    [System.Security.SecurityCritical] // auto-generated_required
    public static AsyncFlowControl SuppressFlow()
    {
    if (IsFlowSuppressed())
    {
    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes"));
    }
    Contract.EndContractBlock();
    AsyncFlowControl afc = new AsyncFlowControl();
    afc.Setup();
    return afc;
    }
    //...
    }//end of ExecutionContext.
  3. AsyncFlowControl

    public struct AsyncFlowControl: IDisposable
    {
    private bool useEC;
    private ExecutionContext _ec;

    //...

    [SecurityCritical]
    internal void Setup()
    {
    useEC = true;
    Thread currentThread = Thread.CurrentThread;
    _ec = currentThread.GetMutableExecutionContext();
    _ec.isFlowSuppressed = true;
    _thread = currentThread;
    }
    }
  4. 线程

    // deliberately not [serializable]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(_Thread))]
    [System.Runtime.InteropServices.ComVisible(true)]
    public sealed class Thread : CriticalFinalizerObject, _Thread
    {

    //...

    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    internal ExecutionContext.Reader GetExecutionContextReader()
    {
    return new ExecutionContext.Reader(m_ExecutionContext);
    }
    }

onlyisFlowSuppressed 设置为 true 以在 StartOperationCommon 方法中传递条件的方法是调用 Setup 方法,并且对 Setup 的唯一调用是在 SuppressFlow 方法中,您已经讨论过了。

As you can see, SuppressFlow is the only solution.

关于c# - 使用 SocketAsyncEventArgs 时是否可以删除 ExecutionContext 和 Thread 分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25270055/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com