Is there a usage pattern that doesn't rely on IDisposable?

I want to create an internal messaging system that can tell me about the duration of a call to some code. I was thinking about ease of use so that the SystemMessage class implements IDisposable.

I set the timestamp during the SystemMessage constructor, and if Dispose was called, I could determine the duration.

The problem is that I do not want to have a GC'ed object. I want it to remain in the MessageCollection.

Is there any other constructor in C # that can give me the convenience of using Statement without stepping on the supposed IDisposable function.

Using (message = Collection.CreateNewMessage("FileDownlading"))
{
    // I wonder how long it is taking me to download this file in production?
    // Lets log it in a message and store for later pondering.
    WebClass.DownloadAFile("You Know This File Is Great.XML");
}
// we fell out of the using statement, message will figure out how long
// it actually took to run.
// This was clean and easy to implement, but so wrong?
+3
source share
12

, GC'ed. , MessageCollection.

Dispose GC'ed - , GC , . MessageCollection, .

Dispose , Dispose , Finalizer, .

, , calss IDisposable, .

. Dispose, - . , itme, - FxCop.

, , - , , :

// C# 3+ lambda syntax
Collection.CreateNewMessage("FileDownlading", () => {
    // I wonder how long it is taking me to download this file in production?    
    // Lets log it in a message and store for later pondering.    
    WebClass.DownloadAFile("You Know This File Is Great.XML");
});

// C# 2 anonymous delegate syntax
Collection.CreateNewMessage("FileDownlading", delegate() {
    // I wonder how long it is taking me to download this file in production?    
    // Lets log it in a message and store for later pondering.    
    WebClass.DownloadAFile("You Know This File Is Great.XML");
});

// Method
void CreateNewMessage(string name, Action action) {
   StopWatch sw = StopWatch.StartNew();
   try {
      action();
   } finally {
      Log("{0} took {1}ms", name, sw.ElapsedMilliseconds);
   }
}

.

+5

?

http://en.wikipedia.org/wiki/Closure_(computer_science)

-... ...

private TimeSpan GetDuration(Action a)
        {
            var start = DateTime.Now;
            a.Invoke();
            var end = DateTime.Now;
            return end.Subtract(start);
        }

        public void something()
        {
            string message;
            var timeSpan = GetDuration(() => { message = "Hello"; } );
        }
+2

, - . , , DownloadAFile ? , , , .

, , try/finally . using - try/finally Dispose.

:

try 
{
    var message = Collection.CreateNewMessage("FileDownlading"); 
    //...
    WebClass.DownloadAFile("You Know This File Is Great.XML");
}
finally 
{
    //You can change this to do logging instead.
    message.Dispose(); 
}
+1

System.Diagnostics.Stopwatch DownloadAFile(), , .

DownloadAFile() ( , , ).

IDisposable .

+1

, , , PostSharp . , , .

http://www.postsharp.org/

, , , , " ", !

+1

, , , , , , , ( , ):

using (MessageTimer timer = Collection.CreateNewTimedMessage("blabla"))
{
   // ...
}

, CreateNewTimedMessage , Message, ( StopWatch - ), using. ( MessageTimer Message, ).

, MessageTimer -, ; using, .

( MessageTimer, , ).

+1

. , , - ( , using():)

var message = Collection.CreateNewMessage("FileDownloading")

try
{
    WebClass.DownloadAFile("You Know This File Is Great.XML");
}
finally
{
    message.HowLongHaveIBeenAlive();
}
0

using , . . - :

message = Collection.CreateNewMessage("FileDownlading");
DateTime dtStart = DateTime.Now;
WebClass.DownloadAFile("You Know This File Is Great.XML");
DateTime dtEnd = DateTime.Now;

// perform comparison here to see how long it took.

// dispose of DateTimes
dtStart = dtEnd = null;
0

IDisposable #, using/Dispose - , .

, , IDisposable, , , . , , , , , , IDisposable.

0

, , , , , IDisposable .

, , .

, GC'ed. , MessageCollection.

. IDisposable GC, , MessageCollection.

, . , Dispose , . , IDisposable, Dispose, ObjectDisposedException, Dispose. .

class Message : IDisposable
{
    private Stopwatch _stopwatch = Stopwatch.StartNew();
    private long _elapsedTicks;
    private string _message;

    public Message(string message)
    {
        _message = message;
    }

    public void Dispose()
    {
       _elapsedTicks = _stopwatch.ElapsedTicks;
       ... anything else including logging the message ...
    }

    ...
}
0

'using' Try/finally, , IDisposable - "" - , .

, , , . , datetime.now; , . , .

Timer . ThreadPool, , - , . , , ThreadPool, .

0

, , ( ).

- , . , , , , , .

The obvious flaw in my example is that I sacrificed arguments such as security, as I was not sure if this is exactly what you are looking for or not. Another problem is that you will need to add a new delegate every time you want to call a method that has a method signature for which you don't have a delegate yet:

using System;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {

            SomeCaller callerOne;
            YetAnotherCaller callerTwo;

            callerOne = new SomeCaller(SomeMethod);
            LogCallDuration(callerOne, new object[] { 15 });

            callerOne = new SomeCaller(SomeOtherMethod);
            LogCallDuration(callerOne, new object[] { 22 });

            callerTwo = new YetAnotherCaller(YetAnotherMethod);
            LogCallDuration(callerTwo, null);

            Console.ReadKey();
        }

        #region "Supporting Methods/Delegates"

        delegate void SomeCaller(int someArg);
        delegate void YetAnotherCaller();

        static void LogCallDuration(Delegate targetMethod, object[] args)
        {
            DateTime start = DateTime.UtcNow;
            targetMethod.DynamicInvoke(args);
            DateTime stop = DateTime.UtcNow;

            TimeSpan duration = stop - start;

            Console.WriteLine(string.Format("Method '{0}' took {1}ms to complete", targetMethod.Method.Name, duration.Milliseconds));

        }

        #endregion "Supporting Methods/Delegates"

        #region "Target methods, these don't have to be in your code"
        static void SomeMethod(int someArg)
        {
            // Do something that takes a little time
            System.Threading.Thread.Sleep(1 + someArg);
        }

        static void SomeOtherMethod(int someArg)
        {
            // Do something that takes a little time
            System.Threading.Thread.Sleep(320 - someArg);
        }

        static void YetAnotherMethod()
        {
            // Do something that takes a little time
            System.Threading.Thread.Sleep(150);
        }
        #endregion "Target methods"
    }
}
0
source

Source: https://habr.com/ru/post/1707490/


All Articles