class object create with using in c# - c#

Create class MustDispose.cs
public class MustDispose
{
public MustDispose()
{
}
}
in.aspx Page
protected void Page_Load(object sender, EventArgs e)
{
using (MustDispose obj = new MustDispose)
{
// use the object
}
}
errorr
Destructors and object.Finalize cannot be called directly. Consider
calling IDisposable.Dispose if available.

You class has to impplement IDisposable, in oder to be used inside using statement.
Example:
public class MustDispose : IDisposable
{
public MustDispose()
{
}
//implement Dispose
public void Dispose()
{
....
}
}
reading from using:
Provides a convenient syntax that ensures the correct use of
IDisposable objects.

You need to implement IDisposable like so:
class TestDispose : IDisposable
{
public TestDispose()
{
...
}
public void Dispose()
{
// dispose of your resources here
}
}
Then you will be able to use it in a using block which automatically calls obj.Dispose at the end of the block.
using (var obj = new TestDispose())
{
...
}
Is like:
var obj = new TestDispose();
try
{
...
}
finally
{
obj.Dispose();
}

Related

Why does Code Analysis flag me when using the null conditional operator with Dispose()?

I have a class that implements IDisposable. I changed my Dispose() method from this:
public void Dispose()
{
if (AccountCreateResetEvent != null)
{
AccountCreateResetEvent.Dispose();
AccountCreateResetEvent = null;
}
}
to this:
public void Dispose()
{
AccountCreateResetEvent?.Dispose();
AccountCreateResetEvent = null;
}
Now I get the following error when running Code Analysis:
'Adapter' contains field 'Adapter.AccountCreateResetEvent' that is of IDisposable type: 'AutoResetEvent'. Change the Dispose method on 'Adapter' to call Dispose or Close on this field.
Is this a quirk of Code Analysis or am I doing something wrong here?
EDIT: Simple full class declaration that reproduces the problem
using System;
using System.Threading;
namespace IDisposableProblem1
{
public sealed class Account : IDisposable
{
private AutoResetEvent AccountResetEvent = new AutoResetEvent(false);
public void Dispose()
{
AccountResetEvent?.Dispose();
AccountResetEvent = null;
}
}
}

Identity Start and End of a method

I am creating Traces for a method and want it to use with a custom attribute. I will decorate each method with TraceMethod.
eg:
[TraceMethod()]
public void SomeMethod()
{
}
public class TraceMethod : Attribute
{
public void StartTrace(){}
public void EndTrace(){}
}
So here,
How to call StartTrace() before the SomeMethod start executing and EndTrace() after the execution of SomeMethod ends? Is it possible?
What you are trying to do is Aspect-Oriented Programming, which is something that is currently not supported out-of-the-box in the .NET world. You will have to use a third-party component; there are some out there, both paid and open sourced.
You could modify method body:
public void SomeMethod()
{
var trace = new Trace();
try
{
... rest of method
}
finally
{
trace.EndTrace();
}
}
public class TraceMethod : Attribute
{
public TraceMethod() => StartTrace();
public void StartTrace() { ... }
public void EndTrace() { ... }
}
Perhaps create a custom class that marks the scope of a function? Create an instance of the class at the start of a function and when function terminates the class gets out of scope and destructor is called.
Constructor and destructor mark beginning and end of a function.
Edit:
As commented it is not garranteed that the destructor is called immediately after the object gets out of scope. Better is to use a using() block:
public void SomeMethod()
{
using (TraceMethod trace = new TraceMethod())
{
}
}
public class TraceMethod : IDisposable
{
public TraceMethod() { StartTrace(); } // Constructor
public void Dispose() { EndTrace(); } // Gets called when leaving the using() block
private void StartTrace() { ... }
private void EndTrace() { ... }
}

Is a ComWrapper class wise to wrap a Interop Com Object

I application that uses a a Interop Com Object. Therefore I had written a wrapper class, to do the freeing in the dispose or if this is not done in the finalizer. So I can use the using keyword, to ensure a freeing is done.
Is using this pattern a good way? Or is there even a class in the Framework that is doing this for me?
class ComWrapper<T> : IDisposable
{
private readonly T comObject;
private bool disposed = false;
public ComWrapper(T comObject)
{
this.comObject = comObject;
}
~ComWrapper()
{
this.Dispose(false);
}
public T ComObject
{
get
{
return this.comObject;
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
Marshal.FinalReleaseComObject(this.comObject);
}
}
I personally wouldn't recommend this because it seems somewhat pointless. But, I would recommend having a static class called Utility, with this method:
public static void disposeComObject<T>(ref T comObject)
{
if(Marshal.IsComObject(comObject) && comObject != null)
{
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Workbook))
{
((Microsoft.Office.Interop.Excel.Workbook))comObject.Save();
((Microsoft.Office.Interop.Excel.Workbook))comObject.Close();
}
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Application))
{
((Microsoft.Office.Interop.Excel.Application))comObject.Quit();
}
Marshal.ReleaseComObject(comObject);
comObject = null;
}
}
Now From Code, you can call this like so
...
Microsoft.Office.Interop.Excel comObject = null;
try{
//Open comObject
//Here I would call some functions, and have nested exceptions
}
catch(nestedException err)
{
//Handle at your discretion
}
finally{
Utility.disposeComObject(ref comObject);
}
This is specific to the Excel Namespace, but adjusting it should be easy enough.

Intercept method calls in a generic class

I have this code:
abstract class CommunicationChannel<Client> : IDisposable where Client : class, IDisposable {
protected Client client;
public void Open() {
try
{
client = CreateClient();
}
catch (Exception)
{
client.Dispose();
throw;
}
}
public virtual void Dispose() {
client.Dispose();
}
private Client CreateClient()
{
return Activator.CreateInstance<Client>();
}
}
class Communicator : CommunicationChannel<Client>
{
// here I have specific methods
void Method1(args) {
Open();
try {
client.Method1(args);
}
catch(Exception) {
// Cleanup
}
}
// this is getting too verbose already
void Method2(args) {
Open();
try {
client.Method2(args);
}
catch(Exception) {
// Cleanup
}
}
}
class Client: IDisposable {
public void Dispose()
{
}
}
I would want in the base class CommunicationChannel to be able to intercept somehow all the calls related to client and handle the exceptions before propagating them to the derived class CommunicationChannel. The generic parameter of the base class can contain different methods (in my example we only have Method 1)
I would ideally want a solution in which I don't have to call CommunicationChannel.CallMethod("Method1", args).
You could make client private and force subclasses to access it in a Func or Action. You can then add you before/after logic:
abstract class CommunicationChannel<Client> : IDisposable where Client : class, IDisposable
{
private Client client;
protected TResult WithClient<TResult>(Func<Client, TResult> f)
{
this.Open();
try
{
return f(client);
}
catch (Exception)
{
//cleanup
}
return default(TResult);
}
protected void WithClient(Action<Client> act)
{
WithClient<object>(c => { act(c); return null; })
}
}
your subclasses can then do:
class Communicator : CommunicationChannel<Client>
{
bool Method1(args)
{
return WithClient<bool>(c => { return c.Method1(args); });
}
}
I think this is a good case to use AOP (Aspect Oriented Programming).
What you could do is set up an aspect which OnEntry, executes the Open method and catches the exceptions with the OnException method.
Then all you have to do is decorate the methods you want to use that aspect on with an Attribute
Ill demonstrate what i mean using PostSharp:
public class CommunicationAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
var communicationObject = args.Instance as CommunicationObject;
communicationObject.Open();
args.FlowBehavior = FlowBehavior.Continue;
}
public override void OnException(MethodExecutionArgs args)
{
_logger.log(string.Format("Exception {0} has occured on method {1}", args.Exception, args.Method.Name));
}
}
Then, decorate your methods with this attribute:
class Communicator : CommunicationChannel<Client>
{
[CommunicationAspect]
void Method1(args)
{
client.Method1(args);
}
[CommunicationAspect]
void Method2(args)
{
client.Method2(args);
}
}
PostSharp is a great framework that makes it really easy to get started, I suggest you look into it.

Can I reference / use COM objects in my finalizer?

I have a COM type (created using tlbimp.exe) and a C# class that wraps this object. I want to perform some clean up in the finalizer for my C# wrapper. Following the guidelines here I might write something like this:
public class MyClass : IDisposable
{
private IMyComObject comObject;
public MyClass()
{
comObject = new MyComObject();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyClass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
// Be tollerant of partially constructed instances
if (comObject != null)
{
comObject.Cleanup();
// Account for object being disposed twice
comObject = null;
}
}
// Other bits go here...
}
I know that finalizers can run in any order and so I should not attempt to use any object that implements a finalizer, however as far as I can tell tlbimp generated COM types don't implement a finalizer and so the above should be OK.
I haven't been able to find any official documentation on this however, so my question is is it safe to reference and use COM objects in a finalizer?
I created a abstract com wrapper class, from which I derive all my com wrapper classes. It works very well. My original code is VB, since I need late binding (this was before C# introduced the dynamic type). The rest of my app is written in c#.
public abstract class ComWrapper : IDisposable
{
protected internal object _comObject;
protected ComWrapper(object comObject)
{
_comObject = comObject;
}
#region " IDisposable Support "
private bool _disposed = false;
protected virtual void FreeManagedObjects()
{
}
protected virtual void FreeUnmanagedObjects()
{
ReleaseComObject(_comObject);
}
private void Dispose(bool disposing)
{
if (!_disposed) {
if (disposing) {
FreeManagedObjects();
}
FreeUnmanagedObjects();
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected override void Finalize()
{
Dispose(false);
base.Finalize();
}
#endregion
}
and
public static class Helpers
{
public static void ReleaseComObject(ref object o)
{
if ((o != null)) {
try {
Marshal.ReleaseComObject(o);
} catch {
} finally {
o = null;
}
}
}
public static string ToDotNetString(object comString)
{
if (comString == null) {
return string.Empty;
}
string s = comString.ToString();
ReleaseComObject(ref comString);
return s;
}
}

Categories

Resources