gpt4 book ai didi

c# - 在操作方法中抛出 HttpResponseException 时处理 HttpResponseMessage 及其内容

转载 作者:太空狗 更新时间:2023-10-30 00:48:03 24 4
gpt4 key购买 nike

我的问题的来源是以下代码,它是 Microsoft documentation 中包含的代码片段的一部分对于 asp.net web api 中的异常处理:

var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent(string.Format("No product with ID = {0}", id)),
ReasonPhrase = "Product ID Not Found"
};
throw new HttpResponseException(resp);

HttpResponseMessageStringContent都实现了IDisposable接口(interface),但是上面代码中没有调用方法IDisposable.Dispose.
这是个问题吗?不处理这些对象是否有任何副作用?

根据 this article一个可能的解决方案是将上面的代码更改为以下代码:

var content = new StringContent(string.Format("No product with ID = {0}", id));
var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = content,
ReasonPhrase = "Product ID Not Found"
};

this.Request.RegisterForDispose(content);
this.Request.RegisterForDispose(resp);

throw new HttpResponseException(resp);

这是否真的有必要,或者是否有可能避免这种情况(根据 Microsoft 文档中显示的内容)?

最佳答案

检查 Microsoft Source for HttpResponseMessage.CS :

protected virtual void Dispose(bool disposing)
{
// The reason for this type to implement IDisposable is that it contains instances of
// types that implement IDisposable (content).
if (disposing && !_disposed)
{
_disposed = true;
if (_content != null)
{
_content.Dispose();
}
}
}

content 是 HttpContent 类型。检查 Microsoft Source for HttpContent.cs :

protected override void Dispose(bool disposing)
{
Debug.Assert(_buffer != null);

ArrayPool<byte>.Shared.Return(_buffer);
_buffer = null;

base.Dispose(disposing);
}

ArrayPool的评论说:

/// Renting and returning buffers with an <see cref="ArrayPool{T}"/> can increase performance
/// in situations where arrays are created and destroyed frequently, resulting in significant
/// memory pressure on the garbage collector.

检查 ArrayPool 的源代码会产生这个可爱的 gem :

    /// <summary>
/// Retrieves a shared <see cref="ArrayPool{T}"/> instance.
/// </summary>
/// <remarks>
/// The shared pool provides a default implementation of <see cref="ArrayPool{T}"/>
/// that's intended for general applicability. It maintains arrays of multiple sizes, and
/// may hand back a larger array than was actually requested, but will never hand back a smaller
/// array than was requested. Renting a buffer from it with <see cref="Rent"/> will result in an
/// existing buffer being taken from the pool if an appropriate buffer is available or in a new
/// buffer being allocated if one is not available.
/// </remarks>
public static ArrayPool<T> Shared
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated(); }
}

ArrayPool 不使用 WeakReference 或任何类似机制来确保正确处理。如果您从 ArrayPool.Shared 租用缓冲区,则必须归还它,否则会导致内存泄漏。

是的,我想说尊重 IDisposable 在这里非常重要。

关于c# - 在操作方法中抛出 HttpResponseException 时处理 HttpResponseMessage 及其内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50473892/

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