Incompatible C # and C + +; ReadFile; how can C # resources immediately release resources __c++

Source: Internet
Author: User
Tags readfile hosting

Problem Statement:

Background: The entire program is written by C #, which invokes the DLL written by C + +.

I am here in the mobile system encountered a problem, is that I called in C # in C # of the serial operation, that is, a new SerialPort object, and then read and write to the serial, and finally close off. At this time I go to call WindowsAPI, but not direct call, but through DllImport a DLL, this DLL is written in C + +, and DLL has opened the same serial and read and write functions, the result will be stuck in ReadFile here, is the interface function in C + +.

Problem Analysis:

The overall feeling is that C # resources are not freed, although close, but resources should not be released. But do not understand things, call C + + Creatfile can be successful, return also have a handle, write serial port can also be successful, is the card in ReadFile not move. Do not know the specific reasons.

So I looked for information on the principles of C # resource release:

First of all, the hosting of C #

So. NET refers to the resource hosting in the end what is meant to be relative to all resources, or to only one aspect of resources. A lot of people don't know much about this, actually. NET refers to only the memory of this aspect, not for all resources, so for stream, database connection, GDI + related objects, as well as COM objects, and so on, these resources are not affected. NET management, collectively known as unmanaged resources. For the release and recovery of memory, the system provides gc-garbage Collector, while for other resources it needs to be released manually.

second, what is garbage?

. NET types are divided into two broad categories, one being the value type and the other being the reference type. The former is allocated on the stack and does not require GC recovery; the latter is allocated on the heap, so its memory release and recovery needs to be done through GC. The GC is all called "garbage Collector", as the name implies is the garbage collector, then only objects called garbage can be collected by GC. In other words, the memory used by a reference type object needs to be recycled by GC, and it needs to be garbage first. So. NET how to determine a reference type object is garbage,. NET's judgment is simple, as long as it is determined that the object or its contained child objects are not valid, then the system thinks it is garbage.

Defining these two basic concepts, let's talk about how the GC works and how it functions. The release and recovery of memory needs to be accompanied by the operation of the program, so the system arranges separate threads for the GC. The GC's job is, in general, to query whether an object in memory is garbage, and then release and recycle it. Then the GC takes a certain priority algorithm for the memory recycle to recycle the memory resource in the round robin. Secondly, there are two kinds of garbage in memory, one is to call the destructor of the object, the other is not need to call. GC for the former recovery needs to be completed in two steps, the first step is to call the object's destructor, the second is to reclaim memory, but note that these two steps are not in the GC one round to complete, that is, two rounds of rotation, compared to the latter, it is only recycled memory.

So what should we do with the program resources, and how do we do it, to make the program more efficient and to consume resources as quickly as possible. As I said before, the resources are divided into two kinds, managed memory resources, this is not need us to worry about, the system has been managed for us; then for unmanaged resources, here again, is the stream, database connection, GDI + related objects, as well as COM objects and so on these resources, We need to release it manually.

How to release, where to put these operations better. NET provides three methods and the most common three, roughly as follows:

<!--[if!supportlists]-->1. <!--[endif]--> destructor;

<!--[if!supportlists]-->2. <!--[endif]--> inherits IDisposable interface and implements Dispose method.

<!--[if!supportlists]-->3. <!--[endif]--> provides the Close method.

As you can see from the previous introduction, the destructor can only be invoked by the GC. It is not possible to determine when it is invoked, so it is not reasonable to use it as a resource release because the resource is not released in time, but it is called by GC to prevent resource leaks, so the destructor can be used as a remedy. The difference between close and dispose is that when the Close method of the object is called, the object is likely to be reused, and the Dispose method has a resource that is marked as useless, that is, the object is destroyed and cannot be used again. For example, common SqlConnection this class, when the Close method is called, you can reopen the database connection through open, and you can call the Dispose method to mark this object as useless and wait for GC recycle when you don't use it completely. Having understood the meaning of both methods, do not distort the two meanings when you add interfaces to your class.

The first is the implementation of these three methods, roughly as follows:

<summary>

The class to show three disposal function

</summary>

public class Disposeclass:idisposable

{

public void Close ()

{

Debug.WriteLine ("Close called!");

}

~disposeclass ()

{

Debug.WriteLine ("destructor called!");

}

#region IDisposable Members

public void Dispose ()

{

Todo:add Disposeclass.dispose Implementation

Debug.WriteLine ("Dispose called!");

}

#endregion

}

It is not a real release for close, except to notice that it needs to be called out, and I don't say much about it here. For destructors, it is not executed immediately after the object has left the scope, only when the process is closed or when the Gc.collect method is invoked, see the following code run results.

private void Create ()

{

Disposeclass MyClass = new Disposeclass ();

}

private void Callgc ()

{

Gc. Collect ();

}

Show destructor

Create ();

Debug.WriteLine ("after created!");

CALLGC ();

The results of the run are:

After created!

destructor called!

Obviously, outside of the CREATE function, the destructor of the MyClass object is not called immediately, but is called until the display call Gc.collect.

You also need to display calls for Dispose, but you can use this keyword for type objects that inherit IDisposable, so that the Dispose method of the object is invoked automatically after the using scope is out. For example:

using (Disposeclass MyClass = new Disposeclass ())

{

Here's operation.

}

The results of the run are as follows:

Dispose called!

For a Dispose implementation like the Disposeclass type, in fact, the GC also needs to invoke the destructor of the object, which, according to the preceding GC process, has at least two steps for the object that needs to invoke the destructor, that is, to invoke the destructor of the object first, Second, reclaim memory. In other words, the Dispose function, as written above, is executed, but the GC still needs to perform the destructor, and a complete dispose function should tell the GC by calling Gc.suppressfinalize (this). So that it doesn't have to call the destructor of the object again. then rewrite the disposeclass as follows:

<summary>

The class to show three disposal function

</summary>

public class Disposeclass:idisposable

{

public void Close ()

{

Debug.WriteLine ("Close called!");

}

~disposeclass ()

{

Debug.WriteLine ("destructor called!");

}

#region IDisposable Members

public void Dispose ()

{

Todo:add Disposeclass.dispose Implementation

Debug.WriteLine ("Dispose called!");

Gc. SuppressFinalize (this);

}

#endregion

}

Test with the following code.

private void Run ()

{

using (Disposeclass MyClass = new Disposeclass ())

{

Here's operation.

}

}

private void Callgc ()

{

Gc. Collect ();

}

Show destructor

Run ();

Debug.WriteLine ("after run!");

CALLGC ();

The results of the operation are as follows:

Dispose called!

After run!

The final solution is to call the Gc.collect () method after close and use it normally.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.