.NET框架自动内存管理(5)

精通.NET内存管理《Pro .NET Memory Management》知识点总结 .NET内存管理不是魔法——理解GC的机械同情(Mechanical Sympathy),才能在性能与资源间找到平衡点。当你能从CPU缓存行的维度思考数组布局,从虚拟地址的视角解构对象生命周期,便是真正掌握了这门黑暗艺术。:2021版(涵盖.NET 5/6,对比JVM内存模型):Konrad Kokosa(微软MVP,GC专家):从CLR源码层解构内存机制,提供生产环境调优方法论。dotnet-counters监控。:《精通.NET内存管理》(验证SafeHandle释放。Handle计数上升。 阅读详情

.NET框架自动内存管理(5)

 

 

 

5.清理非托管资源的Dispose模式

 

 

 

当托管对象封装了非托管资源时,为保证垃圾回收器能回收非托管资源,必须重写Finalize方法,在Finalize方法中封装能够清理非托管资源的代码。有时希望消耗大量内存的非托管资源能够在垃圾回收周期到来之前被回收以提高应用程序的性能,这时就需要手动清理非托管资源。所幸的是,.NET框架类库(FCL)提供了实现手动清理非托管资源的基本框架,这就是Dispose模式。

IDisposable接口是实现Dispose模式的核心。IDisposable接口定义如下:

public interface IDisposable

{

    void Dispose();

}

 在Dispose模式中,所有封装非托管资源的对象都必须实现IDisposable接口,并在Dispose方法中实现非托管资源的清理操作。这样应用程序可以通过IDisposable接口直接调用Dispose方法来释放非托管资源占用的内存,而Finalize方法则成为在没有调用Dispose方法的情况下由垃圾回收器自动启动非托管资源清理的一种防护措施。为保证由应用程序直接调用Dispose方法进行的非托管资源清理操作与垃圾回收器自动启动的非托管资源清理操作过程是一致的,在Dispose模式中,通常在析构函数(也就是重写的Finalize方法)中调用Dispose方法。

使用Dispose模式需要遵循以下原则:

1.      如果基类实现了IDisposable接口,则在派生类的Dispose方法实现中必须调用基类的Dispose方法,以保证封装在基类对象中的非托管资源能够被清理;

2.      对象必须通过在包容层次结构中传播Dispose方法的调用以确保及时释放所有保持的非托管资源。例如,如果对象A分配对象B,则A的Dispose方法实现必须调用B的Dispose方法;

3.      必须确保对象的Dispose方法只被实质调用一次,而且不得引发异常,因为异常将阻断Dispose的调用链。如果对象的Dispose方法被调用多次,必须忽略第一次调用以后的所有调用,否则当非托管资源已释放后再次调用Dispose方法必然发生资源释放错误而不得不引发异常;

4.      由于调用Finalize方法将大大减损性能,所以如果应用程序已显式调用Dispose方法完成了资源清理工作,垃圾回收器就没必要调用对象的Finalize方法了。这时应该在Dispose方法中调用GC.SuppressFinalize方法,以阻止其Finalize方法被垃圾回收器调用,从而提高应用程序性能;

5.      如果资源使用特定的约定表示其已分配状态和已释放状态,例如流或数据库连接,则封装该类资源的对象通常还应提供分配资源的Open方法和释放资源的Close方法。在Close方法中调用Dispose方法;

6.      作为资源释放的最后一道防护措施,实现IDisposable接口的对象通常应重写Finalize方法。

下面的代码示例阐释了Dispose模式的实现原则及实现框架。

/// <summary>
/// This class uses the dispose pattern to provide a skeleton for resource cleanup operations.
/// </summary>
/// <remarks>
/// The class wraps unmanaged resources can be derived from this type.
/// It is the derived class's responsibility to override the protected virtual
/// <see cref="Dispose(bool)"/> method for doing actual cleanup operation.
/// </remarks>
public abstract class DisposeBase : System.IDisposable
{
 #region implements IDisposable interface

/// <summary>
/// This class uses the dispose pattern to provide a skeleton for resource cleanup operations.
/// </summary>
/// <remarks>
/// The class wraps unmanaged resources can be derived from this type.
/// It is the derived class's responsibility to override the protected virtual
/// <see cref="Dispose(bool)"/> method for doing actual cleanup operation.
/// </remarks>
public abstract class DisposeBase : System.IDisposable
{
 #region implements IDisposable interface

/// <summary>
/// This class uses the dispose pattern to provide a skeleton for resource cleanup operations.
/// </summary>
/// <remarks>
/// The class wraps unmanaged resources can be derived from this type.
/// It is the derived class's responsibility to override the protected virtual
/// <see cref="Dispose(bool)"/> method for doing actual cleanup operation.
/// </remarks>
public abstract class DisposeBase : System.IDisposable
{
 #region implements IDisposable interface

 /// <summary>
 /// This public method can be called to deterministically release all resources,
 /// including both managed and unmanaged resources, used by the derived classes.
 /// </summary>
 /// <remarks>
 /// This is not a virtual method
 /// as most classes implementing <see cref="IDisposable"/> interface in FCL make
 /// this method virtual. The derived classes should not override this method.
 /// </remarks>
 public void Dispose()
 {
  // because this object will be explicitly cleaned up, stop the garbage collector
  // from calling the Finalize method.
  GC.SuppressFinalize(this);

 /// <summary>
 /// This public method can be called to deterministically release all resources,
 /// including both managed and unmanaged resources, used by the derived classes.
 /// </summary>
 /// <remarks>
 /// This is not a virtual method
 /// as most classes implementing <see cref="IDisposable"/> interface in FCL make
 /// this method virtual. The derived classes should not override this method.
 /// </remarks>
 public void Dispose()
 {
  // because this object will be explicitly cleaned up, stop the garbage collector
  // from calling the Finalize method.
  GC.SuppressFinalize(this);

 /// <summary>
 /// This public method can be called to deterministically release all resources,
 /// including both managed and unmanaged resources, used by the derived classes.
 /// </summary>
 /// <remarks>
 /// This is not a virtual method
 /// as most classes implementing <see cref="IDisposable"/> interface in FCL make
 /// this method virtual. The derived classes should not override this method.
 /// </remarks>
 public void Dispose()
 {
  // because this object will be explicitly cleaned up, stop the garbage collector
  // from calling the Finalize method.
  GC.SuppressFinalize(this);

  // call the method that actually does the cleanup.
  Dispose(true);
 }

  // call the method that actually does the cleanup.
  Dispose(true);
 }

  // call the method that actually does the cleanup.
  Dispose(true);
 }

 #endregion

 #endregion

 #endregion

 #region virtual Dispose method

 #region virtual Dispose method

 #region virtual Dispose method

 /// <summary>
 /// This method is designed to be overridden by the derived classes to do
 /// the actual clean up operations.
 /// </summary>
 /// <param name="disposing">
 /// A <see langword="bool" /> value to indicate whether this method is called
 /// explicitly by the application or implicitly by the finalizer.
 /// This method executes in two distinct scenarios.
 /// <para>
 /// If <paramref name="disposing" /> is <see langword="true" />,
 /// the method should has been called directly or indirectly by the application
 /// from inside the public <see cref="Dispose()"/> method.
 /// Managed and unmanaged can be disposed.
 /// </para>
 /// <para>
 /// If <paramref name="disposing" /> is <see langword="false" />,
 /// the method should has been called by the garbage collector from inside the
 /// <see cref="Finalize"/> method.
 /// Only unmanaged can be disposed.
 /// </para>
 /// </param>
 /// <remarks>
 /// The derived classes should override this virtual method to do
 /// the actual clean up operations. and call the base class's virtual
 /// <b>Dispose(Boolean)</b> method within the overridden method.
 /// </remarks>
 protected virtual void Dispose(bool disposing)
 {
  // does nothing in the base class.
 }

 /// <summary>
 /// This method is designed to be overridden by the derived classes to do
 /// the actual clean up operations.
 /// </summary>
 /// <param name="disposing">
 /// A <see langword="bool" /> value to indicate whether this method is called
 /// explicitly by the application or implicitly by the finalizer.
 /// This method executes in two distinct scenarios.
 /// <para>
 /// If <paramref name="disposing" /> is <see langword="true" />,
 /// the method should has been called directly or indirectly by the application
 /// from inside the public <see cref="Dispose()"/> method.
 /// Managed and unmanaged can be disposed.
 /// </para>
 /// <para>
 /// If <paramref name="disposing" /> is <see langword="false" />,
 /// the method should has been called by the garbage collector from inside the
 /// <see cref="Finalize"/> method.
 /// Only unmanaged can be disposed.
 /// </para>
 /// </param>
 /// <remarks>
 /// The derived classes should override this virtual method to do
 /// the actual clean up operations. and call the base class's virtual
 /// <b>Dispose(Boolean)</b> method within the overridden method.
 /// </remarks>
 protected virtual void Dispose(bool disposing)
 {
  // does nothing in the base class.
 }

 /// <summary>
 /// This method is designed to be overridden by the derived classes to do
 /// the actual clean up operations.
 /// </summary>
 /// <param name="disposing">
 /// A <see langword="bool" /> value to indicate whether this method is called
 /// explicitly by the application or implicitly by the finalizer.
 /// This method executes in two distinct scenarios.
 /// <para>
 /// If <paramref name="disposing" /> is <see langword="true" />,
 /// the method should has been called directly or indirectly by the application
 /// from inside the public <see cref="Dispose()"/> method.
 /// Managed and unmanaged can be disposed.
 /// </para>
 /// <para>
 /// If <paramref name="disposing" /> is <see langword="false" />,
 /// the method should has been called by the garbage collector from inside the
 /// <see cref="Finalize"/> method.
 /// Only unmanaged can be disposed.
 /// </para>
 /// </param>
 /// <remarks>
 /// The derived classes should override this virtual method to do
 /// the actual clean up operations. and call the base class's virtual
 /// <b>Dispose(Boolean)</b> method within the overridden method.
 /// </remarks>
 protected virtual void Dispose(bool disposing)
 {
  // does nothing in the base class.
 }

 #endregion

 #endregion

 #endregion

 #region finalizer

 #region finalizer

 #region finalizer

 /// <summary>
 /// This <b>Finalize</b> method is called by garbage collection to release
 /// unmanaged resources and perform other clean up operations. It is run
 /// only if the public parameterless <see cref="Dispose()"/> method does not get
 /// called directly by the application.
 /// <para>In C#, finalizers are expressed using destructor syntax.</para>
 /// </summary>
 /// <remarks>Do not override Finalize method in types derived from this class.
 /// The virtual <see cref="Dispose(bool)"/> method with a <see langword="bool" />
 /// parameter is interally called to do the actual clean up operations.
 /// </remarks>
 ~DisposeBase()
 {
  // call the method that actually does the cleanup.
  // calling Dispose(false) is optimal in terms of readability and maintainability.
  Dispose(false);
 }

 /// <summary>
 /// This <b>Finalize</b> method is called by garbage collection to release
 /// unmanaged resources and perform other clean up operations. It is run
 /// only if the public parameterless <see cref="Dispose()"/> method does not get
 /// called directly by the application.
 /// <para>In C#, finalizers are expressed using destructor syntax.</para>
 /// </summary>
 /// <remarks>Do not override Finalize method in types derived from this class.
 /// The virtual <see cref="Dispose(bool)"/> method with a <see langword="bool" />
 /// parameter is interally called to do the actual clean up operations.
 /// </remarks>
 ~DisposeBase()
 {
  // call the method that actually does the cleanup.
  // calling Dispose(false) is optimal in terms of readability and maintainability.
  Dispose(false);
 }

 /// <summary>
 /// This <b>Finalize</b> method is called by garbage collection to release
 /// unmanaged resources and perform other clean up operations. It is run
 /// only if the public parameterless <see cref="Dispose()"/> method does not get
 /// called directly by the application.
 /// <para>In C#, finalizers are expressed using destructor syntax.</para>
 /// </summary>
 /// <remarks>Do not override Finalize method in types derived from this class.
 /// The virtual <see cref="Dispose(bool)"/> method with a <see langword="bool" />
 /// parameter is interally called to do the actual clean up operations.
 /// </remarks>
 ~DisposeBase()
 {
  // call the method that actually does the cleanup.
  // calling Dispose(false) is optimal in terms of readability and maintainability.
  Dispose(false);
 }

 #endregion
}

 #endregion
}

 #endregion
}

// dispose pattern for a derived class.
// This class internally implements the IDisposable interface and impose
// dispose pattern on resource cleanup.
public class ResourceWrapper : DisposeBase
{
 // unmanaged resource pointer
 private IntPtr handle;

// dispose pattern for a derived class.
// This class internally implements the IDisposable interface and impose
// dispose pattern on resource cleanup.
public class ResourceWrapper : DisposeBase
{
 // unmanaged resource pointer
 private IntPtr handle;

// dispose pattern for a derived class.
// This class internally implements the IDisposable interface and impose
// dispose pattern on resource cleanup.
public class ResourceWrapper : DisposeBase
{
 // unmanaged resource pointer
 private IntPtr handle;

 // managed resource reference
 private Component component;

 // managed resource reference
 private Component component;

 // managed resource reference
 private Component component;

 // indicator to track whether Dispose has been called
 private bool disposed = false;

 // indicator to track whether Dispose has been called
 private bool disposed = false;

 // indicator to track whether Dispose has been called
 private bool disposed = false;

 // A more meaningful method to release resources.
 public void Close()
 {
  Dispose();
 }

 // A more meaningful method to release resources.
 public void Close()
 {
  Dispose();
 }

 // A more meaningful method to release resources.
 public void Close()
 {
  Dispose();
 }

 // override the virtual method to do the actual cleanup.
 protected override void Dispose(bool disposing)
 {
  // synchronize threads calling Dispose()/Close() simultaneously
  lock(this)
  {
   // dispose operation should not be done more than once
   if (!this.disposed)
   {
    try
    {
     // if disposing is true, release all the managed and
     // unmanaged resources.
     // this is the case when the Dispose(bool) is called by
     // Dispose()/Close().
     if (disposing)
     {
      // release managed resources
      component.Dispose();
     }
      
     // if disposing is false, only unmanaged resources are released.
     // this is the case when the Dispose(bool) is called by finalizer.
      
     // release unmanaged resources
     if (IntPtr.Zero != handle)
     {
      CloseHandle(handle);
      handle = IntPtr.Zero;
     }

 // override the virtual method to do the actual cleanup.
 protected override void Dispose(bool disposing)
 {
  // synchronize threads calling Dispose()/Close() simultaneously
  lock(this)
  {
   // dispose operation should not be done more than once
   if (!this.disposed)
   {
    try
    {
     // if disposing is true, release all the managed and
     // unmanaged resources.
     // this is the case when the Dispose(bool) is called by
     // Dispose()/Close().
     if (disposing)
     {
      // release managed resources
      component.Dispose();
     }
      
     // if disposing is false, only unmanaged resources are released.
     // this is the case when the Dispose(bool) is called by finalizer.
      
     // release unmanaged resources
     if (IntPtr.Zero != handle)
     {
      CloseHandle(handle);
      handle = IntPtr.Zero;
     }

 // override the virtual method to do the actual cleanup.
 protected override void Dispose(bool disposing)
 {
  // synchronize threads calling Dispose()/Close() simultaneously
  lock(this)
  {
   // dispose operation should not be done more than once
   if (!this.disposed)
   {
    try
    {
     // if disposing is true, release all the managed and
     // unmanaged resources.
     // this is the case when the Dispose(bool) is called by
     // Dispose()/Close().
     if (disposing)
     {
      // release managed resources
      component.Dispose();
     }
      
     // if disposing is false, only unmanaged resources are released.
     // this is the case when the Dispose(bool) is called by finalizer.
      
     // release unmanaged resources
     if (IntPtr.Zero != handle)
     {
      CloseHandle(handle);
      handle = IntPtr.Zero;
     }

     // resources have been released successfully.
     this.disposed = true;
    }
    finally
    {
     // always calls the base class's Dispose(bool) to let it have
     // the opportunity to do its cleanup.
     base.Dispose(disposing);
    }
   }
  }
 }

     // resources have been released successfully.
     this.disposed = true;
    }
    finally
    {
     // always calls the base class's Dispose(bool) to let it have
     // the opportunity to do its cleanup.
     base.Dispose(disposing);
    }
   }
  }
 }

     // resources have been released successfully.
     this.disposed = true;
    }
    finally
    {
     // always calls the base class's Dispose(bool) to let it have
     // the opportunity to do its cleanup.
     base.Dispose(disposing);
    }
   }
  }
 }

 // Private method called to free the unmanaged resource.
 [System.Runtime.InteropServices.DllImport("Kernel32")]
 private extern static Boolean CloseHandle(IntPtr handle);
}

 // Private method called to free the unmanaged resource.
 [System.Runtime.InteropServices.DllImport("Kernel32")]
 private extern static Boolean CloseHandle(IntPtr handle);
}

 // Private method called to free the unmanaged resource.
 [System.Runtime.InteropServices.DllImport("Kernel32")]
 private extern static Boolean CloseHandle(IntPtr handle);
}

1.C#和.NET框架 帮你进入C#世界 阅读详情

相关推荐

.net core 内存管理

在使用 .NET Core 开发时,内存管理是一个非常重要的话题。理解和优化内存管理可以帮助你提高应用程序的性能,避免内存泄漏以及减少垃圾回收的开销

1041

.Net内存管理和垃圾回收

.NET 框架的垃圾回收器管理应用程序的内存分配和释放。每次您使用 new 运算符创建对象时,运行库都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃圾回收器必须执行回收以释放一些内存。垃圾回收器优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被应用程序使用的对象并执行必要的操作来...

每天进步一点点,微笑面对全世界! 350

完整指南:.NET Framework 4.5.2框架详解与应用

NET Framework 4.5.2 是微软在2013年末发布的一个重要更新,它为.NET Framework系列增加了新特性和改进,以适应快速发展的软件开发需求。作为.NET技术栈的一个组成部分,4.5.2版本引入了对异步编程的增强,改进了内存管理,并提升了性能和可靠性,同时强化了安全性。本章将为读者提供一个概览,以便于理解后续各章节中关于性能优化、内存管理、错误修复、开发者体验、异步编程以及跨平台应用支持等主题。

weixin_35906794的博客 1639

HsMod技术方案:基于BepInEx的炉石传说深度定制框架

HsMod是一款基于BepInEx框架开发的炉石传说高级定制解决方案,通过C# IL代码注入技术为游戏提供全方位的功能扩展和性能优化。作为技术爱好者和进阶用户,我们可以深入探索其架构设计、实现原理以及在实际应用中的技术价值。 ## 🔧 核心理念:模块化游戏功能扩展 HsMod的核心设计理念是通过**非侵入式代码注入**实现对炉石传说客户端的深度定制。与传统的游戏修改方式不同,HsMod采用B

gitblog_00475的博客 395

.NET Framework 4.5 x64深入解析与应用

NET Framework 4.5是微软在.NET生态系统中推出的极具影响力的一次更新,它不仅增强了性能和可扩展性,而且提升了开发者的生产力。本章将简要介绍.NET Framework 4.5的编程模型,为后续章节中对关键组件和特性的深入了解打下基础。.NET Framework 4.5在编程模型方面,引入了对现代开发实践的支持,包括异步编程的增强以及基于任务的异步模式(TAP)。它提供了更丰富的API和改进的运行时性能,从而帮助开发者更快速、更简洁地构建可靠的应用程序。

weixin_36019375的博客 1122

最大似然估计、梯度下降、EM算法、坐标上升

主要讲解的是机器学习中参数学习算法之间的区别,以及应用的场景。 最大似然估计: 其中目标函数是对数似然函数。为了求目标函数取最大值时的theta。有两个关机键步骤,第一个是对目标函数进行求导,第二个是另导数等于0,求解后直接得到最优theta。两个步骤缺一不可。 梯度下降: 对目标函数进行求导,利用导函数提供的梯度信息,使参数往梯度下降最快的方向移动一小步,来更新参数。为什

tzl2093的博客 5141

CLR与.NET框架的关系

CLR是.NET框架的核心,提供了执行、管理和优化.NET应用程序所需的基础设施。它负责将中间语言(IL)代码转换为机器代码,并提供内存管理、类型安全、异常处理、安全性、反射和多线程支持等功能。理解CLR的工作原理和功能,对于开发高效、安全的.NET应用程序至关重要。通过CLR,开发者可以专注于业务逻辑,而不必过多关注底层的实现细节。语言互操作性语言互操作性是CLR的一项关键特性,它通过支持多种编程语言和提供统一的类型系统(CTS)来实现不同语言之间的无缝协作。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 935

TPL5010硬件看门狗电路

在做一些采集频率很低的产品的时候,会考虑电池供电,比如表、电气表等,为了控制功耗,往往会在设备不需要工作的时候让它进入低功耗模式。为了设备的稳定性,避免死机后无法恢复,必须配置看门狗,一般的看门狗芯片,喂狗间隔时间是几秒钟。这样在喂狗和低功耗之间就产生了一个矛盾,频繁的喂狗就需要频繁的醒过来,这样功耗就很难做到很低。这颗看门狗芯片,特别适合上面的应用。2小时的间隔意味着主控芯片每2小时醒过来喂狗一次即可,而在2.5V供电的情况下,功耗仅仅35nA,几乎可以忽略不计。

zxm8513优快云博客 3306

[C#] .net 内存管理[2]

基本概念   让我们从一个简单但非常重要的问题开始。 如果 .NET 内存管理全部自动化,您什么时候应该关心它? 你应该关心吗? 正如您可能对我写了这样一本书所期望的那样——我强烈建议您记住每个开发人员处境中的内存。 这只是我们专业性的问题。 我们如何开展工作的结果。 我们是在努力做到最好还是只是制造? 如果我们关注我们工作的质量,我们不应该只担心我们的工作只是工作。 我们应该担心它是如何工作的。 它在 CPU 和内存使用方面是否最佳? 它是否可维护、可测试、为扩展而开放但为修改而关闭? 我们的代码可靠吗?

unity尧明的博客 528

Protege新手必看:从安装到建模的完整指南(附推理功能详解)

本文为Protege新手提供从安装、配置到核心建模的完整实战指南。详细讲解了Java环境准备、本体项目创建、类与属性定义、个体填充等关键步骤,并重点解析了推理功能的配置与使用,帮助读者快速构建可逻辑推理的知识图谱,避开常见陷阱。

numpy6sculptor的博客 796

Apache Paimon-实时数据湖

Flink社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合,推出新一代的 Streaming Lakehouse 技术,促进数据在数据湖上真正实时流动起来,并为用户提供实时离线一体化的开发体验。Flink 社区内部孵化了 Flink Table Store (简称 FTS )子项目,一个真正面向 Streaming 以及 Realtime的数据湖存储项目。

m0_57307642的博客 2192

C# 自动内存管理

开发工具与关键技术:Microsoft Visual Studio 2015、.NET 撰写时间:2019年07月22日 手工内存管理需要开发者管理内存块的分配和重新分配。手工管理内存既耗时又困难。提供自动内存管理可以使开发者从繁重的任务中解放出来。 在大多数情况下,自动内存管理可以在没有反面影响表现和性能的情况下增加代码的质量,提高开发者生产力。 例子: public class Stack ...

⊱MinG⊰ の 博 232

直流电机双闭环调速系统MATLAB仿真

Chopper-Fed DC Motor Drive This example shows a Chopper-Fed DC Motor Drive. Description The DC motor is fed by the DC source through a chopper which consists of GTO thyristor and free-wheeling diode ...

飞行动力的博客 2万+

.NET Framework 框架

.NET Framework 框架

book_dw5189的博客 1988

科研绘图系列:R语言circos图(circos plot)

科研绘图系列:R语言circos图(circos plot)

专注生信领域 3431

fragstats:景观指数趋势分析

优快云@_养乐多_本文将介绍景观指数时间序列的趋势分析,包括趋势类型、斜率、截距等。以及景观指数突变分析所用的软件和 python 代码。结果如下图所示,

养乐多的博客 2859

了解 .NET 运行时与 .NET 框架:基础概念与相互关系

NET框架是由微软开发的一个完整的软件开发平台,它为开发者提供了用于构建、运行和部署应用程序的基础设施。自2002年首次发布以来,.NET框架成为了许多开发者用来构建 Windows 平台应用(例如桌面应用、Web 应用、企业级应用等)的一项核心技术。类库:.NET框架包含大量的预构建类库,开发者可以直接利用这些库来实现常见的功能(例如文件操作、数据库访问、用户界面设计、网络通信等)。这些类库帮助开发者加速开发过程,避免重复造轮子。

Leo的博客 2389

C# 与 PaddleOCR:一行代码实现高效图片文字识别的实战指南

本文介绍了如何使用 PaddleOCRSharp 进行图像文字识别,涵盖了从环境准备到高级功能的完整流程。首先,通过 NuGet 安装 PaddleOCRSharp 并下载预训练模型。接着,展示了单张图片识别的最小化示例和详细实现,包括模型配置、图片预处理和结果输出。进阶功能部分介绍了多语言和竖排文本识别的实现方法。此外,文章还提供了 WinForms 图形界面开发的完整示例,展示了如何通过界面加载图片、执行识别并展示结果。最后,探讨了批量处理优化策略,如并行处理多张图片以提高性能。通过这些步骤,开发者可以

墨夶的博客 1004

C# 图解教程 第5版 —— 第1章 C# 和 .NET 框架

微软公司提供的一个类库,以 C++ 类的形式封装了 Windows 的 API,并包含一个应用程序框架,以减少应用程序开发人员的工作量。一组 .NET 标准,将 .NET 框架的所有组件连接成一个内聚、一致的系统,详细说明了所有软件都必须遵守的规则和约定,如图 1.6 所示。.NET 框架提供庞大的基础类库(BCL),有时也称为 FCL(Framework Class Library,框架类库)。​ CLR 是 .NET 框架的核心组件,位于操作系统的顶层,管理程序的执行,如图 1.5 所示。

zheliku的博客 2801

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Garbage Collection : Automatic Memory Management in the Microsoft .NET Framework 垃圾回收:在微软NET框架自动内存管理(一)

gc c# 垃圾回收 算法

wangtaiping的专栏 1659

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

讨论.NET的替代内存管理策略

在本文中,我们将讨论依赖垃圾收集器作为内存管理策略带来的问题。然后我们讨论可能的替代解决方案,包括微软自己的研究,将非托管堆引入.NET框架。

寒冰屋的专栏 314

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C#基础02-Net框架

对函数式编程更好的支持。

李宥的博客 1183

.net 框架概念及其他框架比较

维度 | .NET Framework | .NET Core | .NET 5+ | Xamarin || 平台支持 | 仅 Windows | 跨平台(Win/Linux/macOS)| 跨平台(全系统) | 移动端(iOS/Android) |- 作用:覆盖全场景开发(桌面、Web、移动、云、IoT),实现“一个框架,多个平台”。

clusterying1的博客 860

38、简述.NET框架中托管代码和⾮托管代码

在.NET框架中,托管代码和非托管代码是两种不同的代码类型,主要区别在于运行环境、内存管理、安全性和跨平台能力等方面

qq_27678663的博客 848

.Net学习框架

HanwinTech第一天.Net培训1. .Net框架结构 1.CLR提供了程序的执行环境,CLR中有一个虚拟机,在许多方面与Java虚拟机类似。 CLR负责激活对象,并对其进行安全检查再将其在内存中布局,执行它们,最后进行垃圾回收。CLR 为编译器提供了托管执行环境和编译服务。 CLR 编译器将源代码编译成中间语言 (IL),然后再以实时 (JIT) 方式执行 IL。 所有源语言都共享 CLR,

黄三清的博客 2558
上一篇: .NET框架自动内存管理(6)
下一篇: .NET框架自动内存管理(4)
OpenBAAN
博客等级 码龄21年 0粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值