Debugging exceptions in a Async/Await (Call Stack) - c#

I use the Async/Await to free my UI-Thread and accomplish multithreading. Now I have a problem when I hit a exception. The Call Stack of my Async parts allways starts with ThreadPoolWorkQue.Dipatch(), which doesn't help me very much.
I found a MSDN-Article Andrew Stasyuk. Async Causality Chain Tracking about it but as I understand it, its not a ready to use solution.
What is the best/easiest way to debug if you use multithreading with Async/Await?

The article you found does a good job of explaining why call stacks don't work the way most of us think they do. Technically, the call stack only tells us where the code is returning to after the current method. In other words, the call stack is "where the code is going", not "where the code came from".
Interestingly, the article does mention a solution in passing, but doesn't expound on it. I have a blog post that goes explains the CallContext solution in detail. Essentially, you use the logical call context to create your own "diagnostic context".
I like the CallContext solution better than the solution presented in the article because it does work will all forms of async code (including fork/join code like Task.WhenAll).
This is the best solution I know of (other than doing something really complex like hooking into the profiling API). Caveats of the CallContext approach:
It only works on .NET 4.5 full. No support for Windows Store apps, .NET 4.0, etc.
You do have to "instrument" your code manually. There's no way AFAIK to inject it automatically.
Exceptions don't capture the logical call context automatically. So this solution works fine if you're breaking into the debugger when exceptions are thrown, but it's not as useful if you're just catching the exceptions in another place and logging them.
The code (depends on the immutable collections NuGet library):
public static class MyStack
{
private static readonly string name = Guid.NewGuid().ToString("N");
private static ImmutableStack<string> CurrentContext
{
get
{
var ret = CallContext.LogicalGetData(name) as ImmutableStack<string>;
return ret ?? ImmutableStack.Create<string>();
}
set
{
CallContext.LogicalSetData(name, value);
}
}
public static IDisposable Push([CallerMemberName] string context = "")
{
CurrentContext = CurrentContext.Push(context);
return new PopWhenDisposed();
}
private static void Pop()
{
CurrentContext = CurrentContext.Pop();
}
private sealed class PopWhenDisposed : IDisposable
{
private bool disposed;
public void Dispose()
{
if (disposed)
return;
Pop();
disposed = true;
}
}
// Keep this in your watch window.
public static string CurrentStack
{
get
{
return string.Join(" ", CurrentContext.Reverse());
}
}
}
Usage:
static async Task SomeWorkAsync()
{
using (MyStack.Push()) // Pushes "SomeWorkAsync"
{
...
}
}
Update: I released a NuGet package (described on my blog) that uses PostSharp to inject the pushes and pops automatically. So getting a good trace should be a lot simpler now.

Related

Per-thread or per-task exception settings?

I have a C# project. Is it possible to write code to the effect that "If an exception should occur while executing thus and such a task (and debugger is available), please break immediately, without unwinding the call stack."
Also, I just want to say, if this isn't possible, I'm fine with an answer to that effect.
You should take a look at the System.Diagnostics.Debugger class (https://msdn.microsoft.com/en-us/library/system.diagnostics.debugger(v=vs.110).aspx)
Using this class you can check to see if the debugger is attached and if it is you can break.
You could also wrap this in a static method on a utility class so you can use it easily
public static class DebuggerHelpers
{
[Conditional("DEBUG")]
public static void BreakIfDebugging()
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break()
}
}
}
The Conditional attribute (https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx) will cause all calls to this method to be omitted when the DEBUG is not defined (AKA Release).
If you want to leave the point where the exception was thrown and yet retain the call stack, you can do it only through logging the StackTrace AFAIK.
public static class Logger
{
...
public static string CurrentStackDefaultLog()
{
// the true value is used to include source file info
var l_CurrentStack = new System.Diagnostics.StackTrace(true);
return l_CurrentStack.ToString();
}
...
}
A good link for implementing this code is given in https://www.codeproject.com/Articles/223611/How-to-log-the-current-call-stack-in-NET by Daniele Mazzeranghi
Based on the other answers, it seems the answer to my question is that it can't be done.

Display custom warning at compile time related to method implementation in C#

In the current context we have two methods Start and Stop. These two methods are invoked from a function sequentially. There can be chances that a person invokes just Start() inside his method but forgets to invoke Stop(). e.g.
private void A()
{
Start();
//Buisness logic goes here
}
In this context when the code is compiled a warning or error needs to be displayed informing that for every Start() there should be a corresponding Stop(). Can somebody suggest ideas on how to go about implementing the same in C#?
The proper way of implementation would be
private void A()
{
Start();
//Buisness logic goes here
Stop();
}
I would suggest you change your pattern to take care of the Start and Stop without ever exposing it to the programmer.
Change your class implementing Start & Stop to implementing an Execute method instead and dont even expose the Start & Stop.
public class MyClass
{
private void Start(){} // old public method
private void Stop(){} // old public method
public void Execute(Action action)
{
Start();
action();
Stop();
}
}
Usage:
var impl = new MyClass();
impl.Execute(() => {
// do something in between start & stop
});
Evk gave a good hint, here is how I would do it in more detail:
Have a class (e.g. StartStop ) implement IDisposable
public class StartStop : IDisposable
{
public StartStop() { Start(); }
public void Dispose() { Stop(); }
protected void Start() { /*...*/ }
protected void Stop() { /*...*/ }
}
Make use of this class with using:
private void A()
{
using( var startStopCaller = new StartStopCaller() )
{
// Your code here
}
}
using will make sure Dispose() and subsequently Stop() will be called except for hard crashes.
This can be approached in many ways, with two primary directions:
If you're using the later versions of the .NET platform, and thus the Roslyn compiler (Defaults from VS2015 and onwards), you can look into writing a compiler plugin that checks this for you. Here are some resources:
Introduction to Scripting with the .NET Compiler Platform (Roslyn)
.NET Compiler Platform SDK
Probably a lot more out there, if you search for "Roslyn" or ".NET Compiler platform".
As some of the comments you got are pointing out, this could be fixed in your code and program design. This is most probably the "correct" way to approach this. Some examples:
Consider implementing IDisposable and use your class in a using statement - however, remember that stopping and disposing of an object might not be the same here. You should make an informed desicion about this with the knowledge you have about the inner workings of your program.
If you're calling these classes from elsewhere, you could let them implement an interface containing both your Start and Stop methods. And then let the calling class simply treat them as this interface, and make sure it calls both methods no matter which implementation it uses.
Re-architect your code to not depend upon running Start() and Stop() sequentially. This might require fundamental design changes to your program and how it works, but it might just be worth it. Both for readability and maintainability.

Is an Action-based Observer not recommended?

For those of us who are new to the great power of IObserver<T> and IObservable<T>, we need to remember that these two interfaces are part of the core of .NET (literally in mscorlib). This is totally different from the Reactive Extensions NuGet package, which can be sadly dismissed as “non-standard.” For pathetic political reasons, I am motivated to confine Rx to one Visual Studio project. This effectively forces me to think up stuff like this:
public class CommunicatorObserver : IObserver<CommunicatorResult>
{
public CommunicatorObserver(Action<CommunicatorResult> actionForObservableNext)
{
this.SetActions(actionForObservableNext, null, null);
}
public CommunicatorObserver(Action<CommunicatorResult> actionForObservableNext, Action<Exception> actionForObservableError)
{
this.SetActions(actionForObservableNext, actionForObservableError, null);
}
public CommunicatorObserver(Action<CommunicatorResult> actionForObservableNext, Action<Exception> actionForObservableError, Action actionForObservableCompleted)
{
this.SetActions(actionForObservableNext, actionForObservableError, actionForObservableCompleted);
}
public void OnCompleted()
{
if (this._actionForObservableCompleted != null) this._actionForObservableCompleted.Invoke();
}
public void OnError(Exception error)
{
if (this._actionForObservableError != null) this._actionForObservableError.Invoke(error);
}
public void OnNext(CommunicatorResult value)
{
if (this._actionForObservableNext != null) this._actionForObservableNext.Invoke(value);
}
public virtual void Subscribe(IObservable<CommunicatorResult> provider)
{
if (provider == null) return;
this._unsubscriber = provider.Subscribe(this);
}
public virtual void Unsubscribe()
{
if (this._unsubscriber != null) this._unsubscriber.Dispose();
}
void SetActions(Action<CommunicatorResult> actionForObservableNext, Action<Exception> actionForObservableError, Action actionForObservableCompleted)
{
this._actionForObservableCompleted = actionForObservableCompleted;
this._actionForObservableError = actionForObservableError;
this._actionForObservableNext = actionForObservableNext;
}
Action _actionForObservableCompleted;
Action<Exception> _actionForObservableError;
Action<CommunicatorResult> _actionForObservableNext;
IDisposable _unsubscriber;
}
My intent is to write my own, general-purpose-but-domain-specific Observer and avoid using the Rx .Subscribe() extension throughout my solution. Are there any pitfalls here? Is this the wrong way to go?
In my opinion, this is a very naive idea.
Rx is much more than just just the implementation you have there (and it appears broken already with the UnSubscribe concept you have).
Will your implementation cater for
Serialization guarantees
a Concurrency model that has been deeply thought through
a concurrency model that can be unit tested deterministicly and at great spped
Cancellation as a first class citizen for both subscriptions and concurrent/scheduled work
The piles of operators that make Rx useful beyond a primitive event model.
The man decades of in the field testing the Rx.NET has been put through
The thousands of Unit tests already in the Rx code base.
Community support when things get more complex than you have initially considered
As per James' advice. Step back and walk away. To go down the path of trying to implement IObservable and IObserver is fool hardy and will cost you in the long run. If your politics dictate that you need to do this, I would look for a new role too.
I've worked in many investment banks with draconian antiquated policies like this; Rx is open source though and even banks allowed me to pull in the source and compile it locally. Can't you even do that?
Rx addresses many non obvious issues that are only going to play out in certain scenarios, so it's hard to comment on your code; but if the source code idea doesn't fly, I can recommend you find a more reasonable employer!
Rx was developed by some very smart people at Microsoft and has been used actively in the field for several years now. You should definitely lobby harder if you can.

Java Equivalent of C# async/await?

I am a normal C# developer but occasionally I develop application in Java. I'm wondering if there is any Java equivalent of C# async/await?
In simple words what is the java equivalent of:
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
var urlContents = await client.GetStringAsync("http://msdn.microsoft.com");
return urlContents.Length;
}
No, there isn't any equivalent of async/await in Java - or even in C# before v5.
It's a fairly complex language feature to build a state machine behind the scenes.
There's relatively little language support for asynchrony/concurrency in Java, but the java.util.concurrent package contains a lot of useful classes around this. (Not quite equivalent to the Task Parallel Library, but the closest approximation to it.)
The await uses a continuation to execute additional code when the asynchronous operation completes (client.GetStringAsync(...)).
So, as the most close approximation I would use a CompletableFuture<T> (the Java 8 equivalent to .net Task<TResult>) based solution to process the Http request asynchronously.
UPDATED on 25-05-2016 to AsyncHttpClient v.2 released on Abril 13th of 2016:
So the Java 8 equivalent to the OP example of AccessTheWebAsync() is the following:
CompletableFuture<Integer> AccessTheWebAsync()
{
AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
return asyncHttpClient
.prepareGet("http://msdn.microsoft.com")
.execute()
.toCompletableFuture()
.thenApply(Response::getResponseBody)
.thenApply(String::length);
}
This usage was taken from the answer to How do I get a CompletableFuture from an Async Http Client request?
and which is according to the new API provided in version 2 of AsyncHttpClient released on Abril 13th of 2016, that has already intrinsic support for CompletableFuture<T>.
Original answer using version 1 of AsyncHttpClient:
To that end we have two possible approaches:
the first one uses non-blocking IO and I call it AccessTheWebAsyncNio. Yet, because the AsyncCompletionHandler is an abstract class (instead of a functional interface) we cannot pass a lambda as argument. So it incurs in inevitable verbosity due to the syntax of anonymous classes. However, this solution is the most close to the execution flow of the given C# example.
the second one is slightly less verbose however it will submit a new Task that ultimately will block a thread on f.get() until the response is complete.
First approach, more verbose but non-blocking:
static CompletableFuture<Integer> AccessTheWebAsyncNio(){
final AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
final CompletableFuture<Integer> promise = new CompletableFuture<>();
asyncHttpClient
.prepareGet("https://msdn.microsoft.com")
.execute(new AsyncCompletionHandler<Response>(){
#Override
public Response onCompleted(Response resp) throws Exception {
promise.complete(resp.getResponseBody().length());
return resp;
}
});
return promise;
}
Second approach less verbose but blocking a thread:
static CompletableFuture<Integer> AccessTheWebAsync(){
try(AsyncHttpClient asyncHttpClient = new AsyncHttpClient()){
Future<Response> f = asyncHttpClient
.prepareGet("https://msdn.microsoft.com")
.execute();
return CompletableFuture.supplyAsync(
() -> return f.join().getResponseBody().length());
}
}
async and await are syntactic sugars. The essence of async and await is state machine. The compiler will transform your async/await code into a state machine.
At the same time, in order for async/await to be really practicable in real projects, we need to have lots of Async I/O library functions already in place. For C#, most original synchronized I/O functions has an alternative Async version. The reason we need these Async functions is because in most cases, your own async/await code will boil down to some library Async method.
The Async version library functions in C# is kind of like the AsynchronousChannel concept in Java. For example, we have AsynchronousFileChannel.read which can either return a Future or execute a callback after the read operation is done. But it’s not exactly the same. All C# Async functions return Tasks (similar to Future but more powerful than Future).
So let’s say Java do support async/await, and we write some code like this:
public static async Future<Byte> readFirstByteAsync(String filePath) {
Path path = Paths.get(filePath);
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);
ByteBuffer buffer = ByteBuffer.allocate(100_000);
await channel.read(buffer, 0, buffer, this);
return buffer.get(0);
}
Then I would imagine the compiler will transform the original async/await code into something like this:
public static Future<Byte> readFirstByteAsync(String filePath) {
CompletableFuture<Byte> result = new CompletableFuture<Byte>();
AsyncHandler ah = new AsyncHandler(result, filePath);
ah.completed(null, null);
return result;
}
And here is the implementation for AsyncHandler:
class AsyncHandler implements CompletionHandler<Integer, ByteBuffer>
{
CompletableFuture<Byte> future;
int state;
String filePath;
public AsyncHandler(CompletableFuture<Byte> future, String filePath)
{
this.future = future;
this.state = 0;
this.filePath = filePath;
}
#Override
public void completed(Integer arg0, ByteBuffer arg1) {
try {
if (state == 0) {
state = 1;
Path path = Paths.get(filePath);
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);
ByteBuffer buffer = ByteBuffer.allocate(100_000);
channel.read(buffer, 0, buffer, this);
return;
} else {
Byte ret = arg1.get(0);
future.complete(ret);
}
} catch (Exception e) {
future.completeExceptionally(e);
}
}
#Override
public void failed(Throwable arg0, ByteBuffer arg1) {
future.completeExceptionally(arg0);
}
}
There is no equivalent of C# async/await in Java at the language level. A concept known as Fibers aka cooperative threads aka lightweight threads could be an interesting alternative. You can find Java libraries providing support for fibers.
Java libraries implementing Fibers
JetLang
Kilim
Quasar
You can read this article (from Quasar) for a nice introduction to fibers. It covers what threads are, how fibers can be implemented on the JVM and has some Quasar specific code.
As it was mentioned, there is no direct equivalent, but very close approximation could be created with Java bytecode modifications (for both async/await-like instructions and underlying continuations implementation).
I'm working right now on a project that implements async/await on top of JavaFlow continuation library, please check https://github.com/vsilaev/java-async-await
No Maven mojo is created yet, but you may run examples with supplied Java agent. Here is how async/await code looks like:
public class AsyncAwaitNioFileChannelDemo {
public static void main(final String[] argv) throws Exception {
...
final AsyncAwaitNioFileChannelDemo demo = new AsyncAwaitNioFileChannelDemo();
final CompletionStage<String> result = demo.processFile("./.project");
System.out.println("Returned to caller " + LocalTime.now());
...
}
public #async CompletionStage<String> processFile(final String fileName) throws IOException {
final Path path = Paths.get(new File(fileName).toURI());
try (
final AsyncFileChannel file = new AsyncFileChannel(
path, Collections.singleton(StandardOpenOption.READ), null
);
final FileLock lock = await(file.lockAll(true))
) {
System.out.println("In process, shared lock: " + lock);
final ByteBuffer buffer = ByteBuffer.allocateDirect((int)file.size());
await( file.read(buffer, 0L) );
System.out.println("In process, bytes read: " + buffer);
buffer.rewind();
final String result = processBytes(buffer);
return asyncResult(result);
} catch (final IOException ex) {
ex.printStackTrace(System.out);
throw ex;
}
}
#async is the annotation that flags a method as asynchronously executable, await() is a function that waits on CompletableFuture using continuations and a call to "return asyncResult(someValue)" is what finalizes associated CompletableFuture/Continuation
As with C#, control flow is preserved and exception handling may be done in regular manner (try/catch like in sequentially executed code)
Java itself has no equivalent features, but third-party libraries exist which offer similar functionality, e.g.Kilim.
Java doesn't have direct equivalent of C# language feature called async/await, however there's a different approach to the problem that async/await tries to solve. It's called project Loom, which will provide virtual threads for high-throughput concurrency. It will be available in some future version of OpenJDK.
This approach also solves "colored function problem" that async/await has.
Similar feature can be also found in Golang (goroutines).
First, understand what async/await is. It is a way for a single-threaded GUI application or an efficient server to run multiple "fibers" or "co-routines" or "lightweight threads" on a single thread.
If you are ok with using ordinary threads, then the Java equivalent is ExecutorService.submit and Future.get. This will block until the task completes, and return the result. Meanwhile, other threads can do work.
If you want the benefit of something like fibers, you need support in the container (I mean in the GUI event loop or in the server HTTP request handler), or by writing your own.
For example, Servlet 3.0 offers asynchronous processing. JavaFX offers javafx.concurrent.Task. These don't have the elegance of language features, though. They work through ordinary callbacks.
There isn't anything native to java that lets you do this like async/await keywords, but what you can do if you really want to is use a CountDownLatch. You could then imitate async/await by passing this around (at least in Java7). This is a common practice in Android unit testing where we have to make an async call (usually a runnable posted by a handler), and then await for the result (count down).
Using this however inside your application as opposed to your test is NOT what I am recommending. That would be extremely shoddy as CountDownLatch depends on you effectively counting down the right number of times and in the right places.
I make and released Java async/await library.
https://github.com/stofu1234/kamaitachi
This library don't need compiler extension, and realize stackless IO processing in Java.
async Task<int> AccessTheWebAsync(){
HttpClient client= new HttpClient();
var urlContents= await client.GetStringAsync("http://msdn.microsoft.com");
  return urlContents.Length;
}
   ↓
//LikeWebApplicationTester.java
BlockingQueue<Integer> AccessTheWebAsync() {
HttpClient client = new HttpClient();
return awaiter.await(
() -> client.GetStringAsync("http://msdn.microsoft.com"),
urlContents -> {
return urlContents.length();
});
}
public void doget(){
BlockingQueue<Integer> lengthQueue=AccessTheWebAsync();
awaiter.awaitVoid(()->lengthQueue.take(),
length->{
System.out.println("Length:"+length);
}
);
}
There is an "equivalent" of await developed by EA: https://github.com/electronicarts/ea-async. Refer to the Java example code:
import static com.ea.async.Async.await;
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
if(!await(bank.decrement(cost))) {
return completedFuture(false);
}
await(inventory.giveItem(itemTypeId));
return completedFuture(true);
}
}
Java has unfortunately no equivalent of async/await. The closest you can get is probably with ListenableFuture from Guava and listener chaining, but it would be still very cumbersome to write for cases involving multiple asynchronous calls, as the nesting level would very quickly grow.
If you're ok with using a different language on top of JVM, fortunately there is async/await in Scala which is a direct C# async/await equivalent with an almost identical syntax and semantics:
https://github.com/scala/async/
Note that although this functionality needed a pretty advanced compiler support in C#, in Scala it could be added as a library thanks to a very powerful macro system in Scala and therefore can be added even to older versions of Scala like 2.10. Additionally Scala is class-compatible with Java, so you can write the async code in Scala and then call it from Java.
There is also another similar project called Akka Dataflow http://doc.akka.io/docs/akka/2.3-M1/scala/dataflow.html which uses different wording but conceptually is very similar, however implemented using delimited continuations, not macros (so it works with even older Scala versions like 2.9).
If you're just after clean code which simulates the same effect as async/await in java and don't mind blocking the thread it is called on until it is finished, such as in a test, you could use something like this code:
interface Async {
void run(Runnable handler);
}
static void await(Async async) throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
async.run(new Runnable() {
#Override
public void run() {
countDownLatch.countDown();
}
});
countDownLatch.await(YOUR_TIMEOUT_VALUE_IN_SECONDS, TimeUnit.SECONDS);
}
await(new Async() {
#Override
public void run(final Runnable handler) {
yourAsyncMethod(new CompletionHandler() {
#Override
public void completion() {
handler.run();
}
});
}
});
I have developed a library JAsync to do this.
It is just released today.
It makes the developer's asynchronous programming experience as close as possible to the usual synchronous programming, including code style and debugging.
Here is the example.
#RestController
#RequestMapping("/employees")
public class MyRestController {
#Inject
private EmployeeRepository employeeRepository;
#Inject
private SalaryRepository salaryRepository;
// The standard JAsync async method must be annotated with the Async annotation, and return a Promise object.
#Async()
private Promise<Double> _getEmployeeTotalSalaryByDepartment(String department) {
double money = 0.0;
// A Mono object can be transformed to the Promise object. So we get a Mono object first.
Mono<List<Employee>> empsMono = employeeRepository.findEmployeeByDepartment(department);
// Transformed the Mono object to the Promise object.
Promise<List<Employee>> empsPromise = JAsync.from(empsMono);
// Use await just like es and c# to get the value of the Promise without blocking the current thread.
for (Employee employee : empsPromise.await()) {
// The method findSalaryByEmployee also return a Mono object. We transform it to the Promise just like above. And then await to get the result.
Salary salary = JAsync.from(salaryRepository.findSalaryByEmployee(employee.id)).await();
money += salary.total;
}
// The async method must return a Promise object, so we use just method to wrap the result to a Promise.
return JAsync.just(money);
}
// This is a normal webflux method.
#GetMapping("/{department}/salary")
public Mono<Double> getEmployeeTotalSalaryByDepartment(#PathVariable String department) {
// Use unwrap method to transform the Promise object back to the Mono object.
return _getEmployeeTotalSalaryByDepartment(department).unwrap(Mono.class);
}
}
And in debug mode, you can see all the variable just like the synchronous code.
The other great thing about this project is that it's one of the few projects of its kind that's still active right now. It's just been released, so it has a lot of potential

.NET: Logging entry / exit without AOP?

I want to be able to log when code execution enters a method and then exits, I was wondering is anyone has any comments on the best way to achieve this?
I know an AOP way of injecting the logging code at runtime exists but I wanted to have a little more control and PostSharp seems to be a pay framework.
What level of logging would you recommend here, I would think DEBUG.
What about logging timings? How long it takes for the method to enter vs exit
I would love to know what others are doing here and what frameworks you are using.
I am looking at going with log4net.
What i was thinking about logging was the parameters and the name of the method and the values of the parameters, and exiting I was thinking of logging the value of the object that I am returning if returning any at all..
What is everyone else doing?
Thanks in advance
If you don't want to use PostSharp (although there's a free version) or have a runtime proxy generated, there's an open-source alternative for static weaving called Afterthought.
Alternatively, you can use one of the profiling tools. VS Ultimate has one built-in.
Well, you could certainly create a "disposable logger" that could "automatically" log your information for the methods that you choose:
public class EnterExitLogger : IDisposable
{
Logger logger;
string name;
public EnterExitLogger(Logger logger, string name, params object [] args)
{
this.logger = logger;
this.name = name;
this.logger.Debug("Entering {0}", this.name);
int i = 0;
foreach (var a in args)
{
this.logger.Debug("arg[{0}] = {1}", i, a);
i++;
}
}
public void Dispose()
{
this.Logger.Debug("Exiting {0}", this.name);
}
}
And then use it like this:
public class MyClass
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public void SomeMethod(int x, int y)
{
using (new EnterExitLogger(logger, "SomeMethod", x, y))
{
//Do your work here
}
}
}
This doesn't strike me as a particularly good idea, and I doubt that I would do it myself. On the other hand, it does achieve some form of Enter/Exit logging without using AOP. If you really want "automatic" Enter/Exit logging, I'm not sure how to achieve it without AOP or Enterprise Library's version (whose name escapes me).
Obviously there will be some overhead in creating and disposing the EnterExitLogger in my proposed solution, but maybe it is not enough to be a negative for you.

Categories

Resources