This might be a really stupid question, especially coming from someone who has worked in .Net for a few years. The question is simple:
Is there a way to wrap a method call + the an event handler, created
from that method in a single method call
Based on my understanding, it is not. Here's an example:
// Starts the long running transaction, when this method completes
// we have no idea whether the transaction actually succeeded/failed
// /finished/etc
public bool BeginLongRunningTransaction(/*args*/)
{
myService.LongRunningTransactionComplete += TransactionComplete;
// Runs the actual transaction - this can take some time
myService.ExecuteLongRunningTransaction();
return true;
}
// Handles the long running transaction complete event
// which allows us to see if the transaction suceeded/failed/etc
private void TransactionComplete(/*args*/)
{
/* Stuff complete! */
}
What will happen, is that a caller will call BeginLongRunningTransaction() method, which will begin the long running transaction but will not be able to return a result of that transaction, as that result will come back in TransactionComplete() event handler. What I am trying to see is whether there is a way to both Begin and return the result of the long running transaction inside the BeginLongRunningTransaction() method, so to the caller,
I am aware of sync-await pattern and also know about inline event handlers. In my understanding, neither of those are able to achieve what I am trying to.
The main reason for this question is simplifying the communication from the subscribing client's point of view.
Many thanks!
Do you mean like this?
public bool DoStuff(/*args*/)
{
myService.StuffComplete += (/*args*/) => { /* Stuff complete! */ };
myService.DoStuff();
return true;
}
But, if you mean that you want the the return value from public bool DoStuff(/*args*/) to be the result of something that happens in /* Stuff complete! */ rather than a hard-coded true then you need to be a bit more clever.
You could do something like this:
public bool DoStuff(/*args*/)
{
bool result = false;
myService.StuffComplete += (/*args*/) =>
{
result = myService.Status;
};
myService.DoStuff();
return result;
}
Here this code expects that the call runs purely on the current thread. If myService.DoStuff() launches a new thread then the myService.StuffComplete handler will run after public bool DoStuff(/*args*/) has completed and you won't get the result you expect.
If you think that myService does invoke new threads behind the scenes (or you wish to have the code run on a background task) then you should look at using Microsoft's Reactive Framework. Then you can do this:
public IObservable<bool> DoStuff(/*args*/)
{
return Observable.Create<bool>(o =>
{
var subscription =
Observable
.FromEventPattern<EventHandler, EventArgs>(
h => myService.StuffComplete += h,
h => myService.StuffComplete -= h)
.Select(x => myService.Status)
.Take(1)
.Subscribe(o);
myService.DoStuff();
return subscription;
});
}
This changes the output of the method from bool to IObservable<bool>, which means that you can observe the result when it is ready.
DoStuff().Subscribe(result => { /* handle result */ };
Try use async-await.
little code example (I was not test):
class YourClass
{
public async Task<bool> DoStuff(/*args*/)
{
var handler = new StuffCompleteHandler(myService);
await handler.GetTask();
return true;
}
private class StuffCompleteHandler
{
private ???? myService;
private TaskCompletionSource<bool> taskSource = new TaskCompletionSource<bool>();
public StuffCompleteHandler(???? myService)
{
this.myService = myService;
this.myService.StuffComplete += this.StuffComplete;
}
private void StuffComplete(/*args*/)
{
this.myService.StuffComplete -= this.StuffComplete;
try
{
/* Stuff complete! */
// do some thing
this.taskSource.SetResult(true);
}
catch (Exception e)
{
this.taskSource.SetException(e);
}
}
public Task GetTask() => this.taskSource.Task;
}
}
Related
When trying to answer the following question, I wrote this piece of code :
using static MyNameSpace.Locker; //So that we don't need to specify the static class name before each call.
public class MainClass
{
public MainMethod()
{
Lock(new object()).Lock(new object()).RunAction(() => Console.WriteLine("Finished"));
}
}
public static class Locker
{
public static async Task<List<object>> Lock(object toLock, int timeout = -1)
{
await Task.Run(() => TryEnter(toLock, timeout));
return new List<object>() { toLock };
}
public static async Task<List<object>> Lock(
this Task<List<object>> lockedChain,
object toLock,
int timeout = -1)
{
await Task.Run(() => TryEnter(toLock, timeout));
await lockedChain;
lockedChain.Result.Add(toLock)
return lockedChain.Result;
}
public static async void RunAction(this Task<List<object>> lockChain, Action toRun)
{
await lockChain;
try
{
toRun.Invoke();
}
finally
{
foreach (var chainMember in lockChain.Result)
{
Monitor.Exit(chainMember);
}
}
}
private static void TryEnter(object toLock, int timeout = -1)
{
var success = false;
if (timeout > 0)
{
success = Monitor.TryEnter(toLock, timeout);
}
else
{
success = Monitor.TryEnter(toLock);
}
if (!success)
{
throw new TimeoutException();
}
}
}
But as some user rightfully remarked, this won't work for a very simple reason : Since the methods are async, they may not run on the same thread, thus throwing an exception when trying to release the Monitor.
How would one go to ensure the Enter and Exit method of the monitor a run on the same thread ?
Instead of forcing the lock operations onto the same thread which is nearly impossible, use a lock that is not thread-affine: SemaphoreSlim. It has native async support as well (as opposed to blocking).
In the original question that you linked to I'd go with this answer instead. Seems cleaner than the chain solution which contains a lot of artificial complexity. Code quality is not so much about the specific call syntax being used. Just by putting things in a syntactic chain you cannot reduce complexity much.
In particular the chain solution is just a complicated way of saying Lock(new [] { lock1, lock2 }, () => ...); I think. All the chain does it build up a list. using makes this even simpler because it does away with the lambda. Lambdas are less composable because you can't return from the lambda like you can from using. I think you should target this:
using (MultiLock(new [] { lock1, lock2 }, timeout)) {
//...
}
Here's the simplified case. I have a class that stores a delegate that it will call on completion:
public class Animation
{
public delegate void AnimationEnd();
public event AnimationEnd OnEnd;
}
I have another utility class that I want to subscribe to various delegates. On construction I want itself to register to the delegate, but other than that it doesn't care about the type. The thing is, I don't know how to express that in the type system. Here's my pseudo-C#
public class WaitForDelegate
{
public delegateFired = false;
// How to express the generic type here?
public WaitForDelegate<F that's a delegate>(F trigger)
{
trigger += () => { delegateFired = true; };
}
}
Thanks in advance!
Thanks to Alberto Monteiro, I just use System.Action as the type for the event. My question now is, how to pass the event to the constructor so it can register itself? This might be a very dumb question.
public class Example
{
Animation animation; // assume initialized
public void example()
{
// Here I can't pass the delegate, and get an error like
// "The event can only appear on the left hand side of += or -="
WaitForDelegate waiter = new WaitForDelegate(animation.OnEnd);
}
}
I'm afraid you can't do what you're asking.
First up, you can't constrain by delegates. The closest code to legal C# is this:
public class WaitForDelegate<F> where F : System.Delegate
{
public bool delegateFired = false;
public WaitForDelegate(F trigger)
{
trigger += () => { delegateFired = true; };
}
}
But it won't compile.
But the bigger problem is that you can't pass delegates around like this anyway.
Consider this simplified class:
public class WaitForDelegate
{
public WaitForDelegate(Action trigger)
{
trigger += () => { Console.WriteLine("trigger"); };
}
}
I then try to use it like this:
Action bar = () => Console.WriteLine("bar");
var wfd = new WaitForDelegate(bar);
bar();
The only output from this is:
bar
The word trigger doesn't appear. This is because delegates are copied by value so that the line trigger += () => { Console.WriteLine("trigger"); }; is only attaching the handler to trigger and not bar at all.
The way that you can make all of this work is to stop using events and use Microsoft's Reactive Extensions (NuGet "Rx-Main") which allows you to turn events into LINQ-based IObservable<T> instances that can get passed around.
Here's how my example code above would then work:
public class WaitForDelegate
{
public WaitForDelegate(IObservable<Unit> trigger)
{
trigger.Subscribe(_ => { Console.WriteLine("trigger"); });
}
}
And you now call it like:
Action bar = () => Console.WriteLine("bar");
var wfd = new WaitForDelegate(Observable.FromEvent(h => bar += h, h => bar -= h));
bar();
This now produces the output:
bar
trigger
Notice that the Observable.FromEvent call contains the code to attach and detach the handler in a scope that has access to do so. It allows the final subscription call to be unattached with a call to .Dispose().
I've made this class quite simple, but a more complete version would be this:
public class WaitForDelegate : IDisposable
{
private IDisposable _subscription;
public WaitForDelegate(IObservable<Unit> trigger)
{
_subscription = trigger.Subscribe(_ => { Console.WriteLine("trigger"); });
}
public void Dispose()
{
_subscription.Dispose();
}
}
An alternative if you don't want to go for the full use of Rx is to do this:
public class WaitForDelegate : IDisposable
{
private Action _detach;
public WaitForDelegate(Action<Action> add, Action<Action> remove)
{
Action handler = () => Console.WriteLine("trigger");
_detach = () => remove(handler);
add(handler);
}
public void Dispose()
{
if (_detach != null)
{
_detach();
_detach = null;
}
}
}
You call it like this:
Action bar = () => Console.WriteLine("bar");
var wfd = new WaitForDelegate(h => bar += h, h => bar -= h);
bar();
That still does the correct output.
In .NET there is already a delegate that doesn't receive no parameters, it is the Action
So you Animation class could be like that:
public class Animation
{
public event Action OnEnd;
}
But you can pass events as parameters, if you try that you will receive this compilation error
The event can only appear on the left hand side of += or -="
So lets create a interface, and declare the event there
public interface IAnimation
{
event Action OnEnd;
}
Using the interface approach you have no external dependencies and you can have many classes that implements that, also is a good practice, depends of abstractions instead concrete types. There is acronym called SOLID that explain 5 principles about better OO code.
And then your animation class implements that
Obs.: The CallEnd method is just for test purpose
public class Animation : IAnimation
{
public event Action OnEnd;
public void CallEnd()
{
OnEnd();
}
}
And now you WaitForDelegate will receive a IAnimation, so the class can handle any class that implements the IAnimation class
public class WaitForDelegate<T> where T : IAnimation
{
public WaitForDelegate(T animation)
{
animation.OnEnd += () => { Console.WriteLine("trigger"); };
}
}
Then we can test the code that we did with the following code
public static void Main(string[] args)
{
var a = new Animation();
var waitForDelegate = new WaitForDelegate<IAnimation>(a);
a.CallEnd();
}
The result is
trigger
Here is the working version on dotnetfiddle
https://dotnetfiddle.net/1mejBL
Important tip
If you are working with multithread, you must take some caution to avoid Null Reference Exception
Let's look again the CallEnd method that I've added for test
public void CallEnd()
{
OnEnd();
}
OnEnd event could have not value, and then if you try to call it, you will receive Null Reference Exception.
So if you are using C# 5 or lower, do something like this
public void CallEnd()
{
var #event = OnEnd;
if (#event != null)
#event();
}
With C# 6 it could be like that
public void CallEnd()
=> OnEnd?.Invoke();
More explanation, you could have this code
public void CallEnd()
{
if (OnEnd != null)
OnEnd();
}
This code that is above, probably make you think that you are safe from Null Reference Exception, but with multithread solution, you aren't. That's because the OnEnd event could be set to null between the execution of if (OnEnd != null) and OnEnd();
There is a nice article by Jon Skeet about it, you cann see Clean event handler invocation with C# 6
Take the following classes as an example.
public class A
{
// ...
void Foo(S myStruct){...}
}
public class B
{
public A test;
// ...
void Bar()
{
S myStruct = new S();
test.Foo(myStruct);
}
}
Now, I want the method-call test.Foo(myStruct) to be an asynchronous call ('fire-and-forget'). The bar-method needs to return as soon as possible. Documentation around delegates, BeginInvoke, EndInvoke, the ThreadPool etc. isn't helping me find a solution.
Is this a valid solution?
// Is using the `EndInvoke` method as the callback delegate valid?
foo.BeginInvoke(myStruct, foo.EndInvoke, null);
You are not required to call EndInvoke; not calling it merely means:
You don't get the return value from the method.
Any exceptions thrown during the method execution will simply disappear.
It sounds like you want to 'fire-and-forget', so the easiest way to do this is to use an anonymous delegate, for example:
var del = new Action(foo.Bar);
del.BeginInvoke(iar =>
{
try
{
del.EndInvoke(iar);
}
catch (Exception ex)
{
// Log the message?
}
}, null);
This is what happens when you execute this code:
A new thread is allocated (put simply) for the delegate.
The thread is given the delegate del and the anonymous delegate (iar => ...).
The thread executes del.
When it is finished executing (or an exception occurs) the result or exception is stored and the anonymous delegate is executed.
Inside the anonymous delegate, when EndInvoke is called the result from the method is either returned, or the exception is thrown (if one occurred).
Note that the above example is very different from:
// This is pointless and is still, essentially, synchronous.
del.EndInvoke(del.BeginInvoke(null, null));
Edit: You should always call End*. I've never found a scenario where not calling it presents a problem, however that is an implementation detail and is relying on undocumented behavior.
Finally your solution would crash the process if an exception is thrown, you can simply pass null as the delegate if you don't care about the exception (del.BeginInvoke(myStruct, null, null);). So as a final example what you are looking for is probably:
public class A
{
// ...
void Foo(S myStruct){...}
void FooAsync(S myStruct)
{
var del = new Action<S>(Foo);
del.BeginInvoke(myStruct, SuppressException, del);
}
static void SuppressException(IAsyncResult ar)
{
try
{
((Action<S>)ar.AsyncState).EndInvoke(ar);
}
catch
{
// TODO: Log
}
}
}
I would say that your best option is to use the ThreadPool:
void bar()
{
ThreadPool.QueueUserWorkItem(o=>
{
S myStruct = new S();
test.foo(myStruct);
});
}
This will queue the snippet for execution in a separate thread. Now you also have to be careful about something else: if you have multiple threads accessing the same instance of A and that instance modifies a variable, then you must ensure that you do proper synchronization of the variable.
public class A
{
private double sum;
private volatile bool running;
private readonly object sync;
public A()
{
sum = 0.0;
running = true;
sync = new object();
}
public void foo(S myStruct)
{
// You need to synchronize the whole block because you can get a race
// condition (i.e. running can be set to false after you've checked
// the flag and then you would be adding the sum when you're not
// supposed to be).
lock(sync)
{
if(running)
{
sum+=myStruct.Value;
}
}
}
public void stop()
{
// you don't need to synchronize here since the flag is volatile
running = false;
}
}
You can use the Callback model explained # What is AsyncCallback?
That way your EndInvoke will not be in bar(), but in a separate callback method.
In the example, the EndRead (corresponding to EndInvoke is in the callback method called CompleteRead rather than the calling method TestCallbackAPM corresponding to bar)
This is an option:
ThreadPool.QueueUserWorkItem(bcl =>
{
var bcList = (List<BarcodeColumn>)bcl;
IAsyncResult iftAR = this.dataGridView1.BeginInvoke((MethodInvoker)delegate
{
int x = this.dataGridView1.Rows[0].Cells.Count - 1;
for (int i = 0; i < this.dataGridView1.Rows.Count - 1; i++)
{
try
{
string imgPath = bcList[i].GifPath;
Image bmpImage = Image.FromFile(imgPath);
this.dataGridView1.Rows[i].Cells[x].Value =bmpImage;
}
catch (Exception)
{
continue;
}
}
});
while (!iftAR.IsCompleted) { /* wait this*/ }
}, barcodeList);
I'm working on a little technical framework for CF.NET and my question is, how should I code the asynchronous part? Read many things on MSDN but isn't clear for me.
So, here is the code :
public class A
{
public IAsyncResult BeginExecute(AsyncCallback callback)
{
// What should I put here ?
}
public void EndExecute()
{
// What should I put here ?
}
public void Execute()
{
Thread.Sleep(1000 * 10);
}
}
If someone can help me...
Thanks !
You could use a delegate:
public class A
{
public void Execute()
{
Thread.Sleep(1000 * 3);
}
}
class Program
{
static void Main()
{
var a = new A();
Action del = (() => a.Execute());
var result = del.BeginInvoke(state =>
{
((Action)state.AsyncState).EndInvoke(state);
Console.WriteLine("finished");
}, del);
Console.ReadLine();
}
}
UPDATE:
As requested in the comments section here's a sample implementation:
public class A
{
private Action _delegate;
private AutoResetEvent _asyncActiveEvent;
public IAsyncResult BeginExecute(AsyncCallback callback, object state)
{
_delegate = () => Execute();
if (_asyncActiveEvent == null)
{
bool flag = false;
try
{
Monitor.Enter(this, ref flag);
if (_asyncActiveEvent == null)
{
_asyncActiveEvent = new AutoResetEvent(true);
}
}
finally
{
if (flag)
{
Monitor.Exit(this);
}
}
}
_asyncActiveEvent.WaitOne();
return _delegate.BeginInvoke(callback, state);
}
public void EndExecute(IAsyncResult result)
{
try
{
_delegate.EndInvoke(result);
}
finally
{
_delegate = null;
_asyncActiveEvent.Set();
}
}
private void Execute()
{
Thread.Sleep(1000 * 3);
}
}
class Program
{
static void Main()
{
A a = new A();
a.BeginExecute(state =>
{
Console.WriteLine("finished");
((A)state.AsyncState).EndExecute(state);
}, a);
Console.ReadLine();
}
}
You don't need to do anything special, cause the caller should call you method async,
He define a new delegate pointing to you method, and use the .net to call your method asynchronously.
On BeginExecute you have to start the asynchronous operation (possibly start execute in a separate thread) and return as quick as possible. Execute has to call the AsyncCallback at the end of all operations so that who use the async operation gets aware and get the result. EndExecute has to stop a previously started async operation (possibly interrupting the thread launched by BeginExecute).
Without more details this is the best I can do.
If you want to run piece of code asynchronously, you should use BackgroundWorker. Unless of course, the code you are calling doesn't support asynchronous operation natively. Just like Read/Write methods or service calls.
If you want to notify, that the asynchronous operation has finished, use delegate or event callback.
In the following code sample I have an Async Calculator class. This is injected with an ICalc, which will be a syncronous calculator. I use dependency injecting and mock the ICalc because this resembles my true scenario, though I guess the mocking isn't really of relevance to the question. The AsyncCalc has a function which will call another function asynchronously - taking a callback as parameter. And when the async function call finishes the callback will be triggered with the result.
Now I want to test my asynchronous function - checking that the callback is triggered with the expected parameter. This code seems to work. However, I feel like it might blow up at any time - and my concern is race condition of the callback to finish before the function ends and the test is terminated - as this will be run in a separate thread.
My question now is if I'm on the right track unit testing the async function, or if anyone can help me get on the right track..? What would feel better is if I could ensure that the callback is triggered right away - and preferably on the same thread I guess? Can/Should it be done?
public interface ICalc
{
int AddNumbers(int a, int b);
}
public class AsyncCalc
{
private readonly ICalc _calc;
public delegate void ResultProcessor(int result);
public delegate int AddNumbersAsyncCaller(int a, int b);
public AsyncCalc(ICalc calc)
{
_calc = calc;
}
public void AddNumbers(int a, int b, ResultProcessor resultProcessor)
{
var caller = new AddNumbersAsyncCaller(_calc.AddNumbers);
caller.BeginInvoke(a, b, new AsyncCallback(AddNumbersCallbackMethod), resultProcessor);
}
public void AddNumbersCallbackMethod(IAsyncResult ar)
{
var result = (AsyncResult)ar;
var caller = (AddNumbersAsyncCaller)result.AsyncDelegate;
var resultFromAdd = caller.EndInvoke(ar);
var resultProcessor = ar.AsyncState as ResultProcessor;
if (resultProcessor == null) return;
resultProcessor(resultFromAdd);
}
}
[Test]
public void TestingAsyncCalc()
{
var mocks = new MockRepository();
var fakeCalc = mocks.DynamicMock<ICalc>();
using (mocks.Record())
{
fakeCalc.AddNumbers(1, 2);
LastCall.Return(3);
}
var asyncCalc = new AsyncCalc(fakeCalc);
asyncCalc.AddNumbers(1, 2, TestResultProcessor);
}
public void TestResultProcessor(int result)
{
Assert.AreEqual(3, result);
}
You could use a ManualResetEvent to synchronize your threads.
In the following example, the test thread will block on the call to completion.WaitOne().
The callback for the async calculation stores the result and then signals the event by calling completion.Set().
[Test]
public void TestingAsyncCalc()
{
var mocks = new MockRepository();
var fakeCalc = mocks.DynamicMock<ICalc>();
using (mocks.Record())
{
fakeCalc.AddNumbers(1, 2);
LastCall.Return(3);
}
var asyncCalc = new AsyncCalc(fakeCalc);
var completion = new ManualResetEvent(false);
int result = 0;
asyncCalc.AddNumbers(1, 2, r => { result = r; completion.Set(); });
completion.WaitOne();
Assert.AreEqual(3, calcResult);
}
// ** USING AN ANONYMOUS METHOD INSTEAD
// public void TestResultProcessor(int result)
// {
// Assert.AreEqual(3, result);
// }
You could also use a "test runner" class to run the asserts in a loop. The loop would run the asserts in a try/catch. The exception handler would simply try to run the asserts again until a timeout has expired. I recently wrote a blog post about this technique. The example is in groovy, but is applicable to any language. Instead of passing a Closure, you would pass a Action in c#.
http://www.greenmoonsoftware.com/2013/08/asynchronous-functional-testing/