C# syntax I wish for
-
Not sure where to post that, (there might some sort of MSDN link somewhere) for now I just post there. "Sometimes" one has to wait for an event to be triggered (once) and then do something, I'd like to write a
WaitForEvent()
method. Unfortunately, due to the particular of event syntax, I can't and I have to write one wait for *that* event method for every single event I am interested in!... :(( Mmm... case for a code sinppet me just think! :omg: :-\ :rolleyes: In any case here is the syntax for a specific event:Task WaitForThatEventAsync(Foo source)
{
var res = new TaskCompletionSource<bool>();
EventHandler eh = null;
eh = (o, e) =>
{
source.ThatEvent -= eh;
res.TrySetResult(true);
};
source.ThatEvent += eh;
return res.Task;
}EDIT My explanation seem confusing.. another explanation is that I would like to be able to write a "general purpose"
WaitForEvent()
extension method that transform this cluncky codeEventHandler ev = null;
ev = (o, e) => {
source.Event -= eh;
DoSomething();
};
source.Event += eh;into this elegant code
await source.Event.WaitForEvent()
DoSomething();where both do the exact same thing! Sadly this is not possible right now... I have a to write a new
WaitForThatEvent()
method for each event I am interested in... :(( but it would be cool. Would make ReactiveC# better looking too.A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
By the way, the more I think about this, you can do what you want rather elegantly, using RX. If you view an event as an Observable, then it would be fairly simple to just observe that event and react to it. When I have a couple of free minutes, I'll write you a general purpose example that shows how to do this (and to wait for pretty much any event).
This space for rent
-
Not sure where to post that, (there might some sort of MSDN link somewhere) for now I just post there. "Sometimes" one has to wait for an event to be triggered (once) and then do something, I'd like to write a
WaitForEvent()
method. Unfortunately, due to the particular of event syntax, I can't and I have to write one wait for *that* event method for every single event I am interested in!... :(( Mmm... case for a code sinppet me just think! :omg: :-\ :rolleyes: In any case here is the syntax for a specific event:Task WaitForThatEventAsync(Foo source)
{
var res = new TaskCompletionSource<bool>();
EventHandler eh = null;
eh = (o, e) =>
{
source.ThatEvent -= eh;
res.TrySetResult(true);
};
source.ThatEvent += eh;
return res.Task;
}EDIT My explanation seem confusing.. another explanation is that I would like to be able to write a "general purpose"
WaitForEvent()
extension method that transform this cluncky codeEventHandler ev = null;
ev = (o, e) => {
source.Event -= eh;
DoSomething();
};
source.Event += eh;into this elegant code
await source.Event.WaitForEvent()
DoSomething();where both do the exact same thing! Sadly this is not possible right now... I have a to write a new
WaitForThatEvent()
method for each event I am interested in... :(( but it would be cool. Would make ReactiveC# better looking too.A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
I understand what you mean. We also have been using such a pattern (your less elegent one) for sometimes. The event property of an object is essentially a list of handlers for the event, which is designed before the introduction of async/await syntax for asynchronous programming. So it would be "un-natural" to have a method for it at the time. But yeah, I would also vote for something like that for events to complete the circle (for the introduction of async/await syntax).
Find more in 1-NET: connects your resources anywhere[^]. Email searcher Email Aggregation Manager[^].
-
Not sure where to post that, (there might some sort of MSDN link somewhere) for now I just post there. "Sometimes" one has to wait for an event to be triggered (once) and then do something, I'd like to write a
WaitForEvent()
method. Unfortunately, due to the particular of event syntax, I can't and I have to write one wait for *that* event method for every single event I am interested in!... :(( Mmm... case for a code sinppet me just think! :omg: :-\ :rolleyes: In any case here is the syntax for a specific event:Task WaitForThatEventAsync(Foo source)
{
var res = new TaskCompletionSource<bool>();
EventHandler eh = null;
eh = (o, e) =>
{
source.ThatEvent -= eh;
res.TrySetResult(true);
};
source.ThatEvent += eh;
return res.Task;
}EDIT My explanation seem confusing.. another explanation is that I would like to be able to write a "general purpose"
WaitForEvent()
extension method that transform this cluncky codeEventHandler ev = null;
ev = (o, e) => {
source.Event -= eh;
DoSomething();
};
source.Event += eh;into this elegant code
await source.Event.WaitForEvent()
DoSomething();where both do the exact same thing! Sadly this is not possible right now... I have a to write a new
WaitForThatEvent()
method for each event I am interested in... :(( but it would be cool. Would make ReactiveC# better looking too.A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
I like that syntax! Where is the problem in writing a general purpose method that does this? (First time I'm posting here! Hey everyone! :))
-
By the way, the more I think about this, you can do what you want rather elegantly, using RX. If you view an event as an Observable, then it would be fairly simple to just observe that event and react to it. When I have a couple of free minutes, I'll write you a general purpose example that shows how to do this (and to wait for pretty much any event).
This space for rent
Your code is eagerly awaited :)
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
-
By the way, the more I think about this, you can do what you want rather elegantly, using RX. If you view an event as an Observable, then it would be fairly simple to just observe that event and react to it. When I have a couple of free minutes, I'll write you a general purpose example that shows how to do this (and to wait for pretty much any event).
This space for rent
Reactive use a lot of callback as far as I remember... What I am trying is to make the code seemingly linear and callback free, using
await
.. (handy for try/catch, easier to understand the flow as well) that said.. I would be curious to see what you come back with! :)A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
-
I understand what you mean. We also have been using such a pattern (your less elegent one) for sometimes. The event property of an object is essentially a list of handlers for the event, which is designed before the introduction of async/await syntax for asynchronous programming. So it would be "un-natural" to have a method for it at the time. But yeah, I would also vote for something like that for events to complete the circle (for the introduction of async/await syntax).
Find more in 1-NET: connects your resources anywhere[^]. Email searcher Email Aggregation Manager[^].
Glad someone understand! :)
A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
-
It's not really a question at all... Just some meta.. programatical musing...
A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
If it looks like code, smells like code, and walks like code, I think it's code, and having this kind of discussion here means that in the long run CodeProject will not benefit as much as if the discussion were in the language forum ... because this kind of content gets "drowned" in the flood of Lounge posts. It's an interesting topic, and becoming a compelling conversation. cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
-
How is that different? It is better looking! turning that basic version
EventHandler ev = null;
ev = (o, e) => {
source.Event -= eh;
DoSomething();
};
source.Event += eh;into that elegant version
await source.Event.WaitForEvent()
DoSomething();Can't you appreciate the beautiful simplicity and easier code flow of the second version?! :omg: Added bonus: DoSomething() will try to be in the same thread as the start of the method!!
A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
I believe you're correct in that you can't do this on the event itself, but you could make something nearly as good (depending on your definition of 'nearly as good').
await source.WaitForEvent(nameof(source.Event));
Would be possible. Using nameof in VS2015 means you have any issues with refactoring, though it is a bit uglier than your preferred syntax. Something like the following would implement the method (and returns the EventArgs if you need them). An alternate overload would be needed for non-generic event handler based evevents, but that's not hard.
public static class EventExtensions
{
public static Task WaitForEvent(this object eventSource, string eventName) where T : EventArgs
{
var tcs = new System.Threading.Tasks.TaskCompletionSource();
var eventInfo = eventSource.GetType().GetEvent(eventName);EventHandler eventHandler = null; eventHandler = new EventHandler( (source, e) => { eventInfo.RemoveEventHandler(eventSource, eventHandler); tcs.TrySetResult(e); } ); eventInfo.AddEventHandler(eventSource, eventHandler); return tcs.Task; } }
-
I believe you're correct in that you can't do this on the event itself, but you could make something nearly as good (depending on your definition of 'nearly as good').
await source.WaitForEvent(nameof(source.Event));
Would be possible. Using nameof in VS2015 means you have any issues with refactoring, though it is a bit uglier than your preferred syntax. Something like the following would implement the method (and returns the EventArgs if you need them). An alternate overload would be needed for non-generic event handler based evevents, but that's not hard.
public static class EventExtensions
{
public static Task WaitForEvent(this object eventSource, string eventName) where T : EventArgs
{
var tcs = new System.Threading.Tasks.TaskCompletionSource();
var eventInfo = eventSource.GetType().GetEvent(eventName);EventHandler eventHandler = null; eventHandler = new EventHandler( (source, e) => { eventInfo.RemoveEventHandler(eventSource, eventHandler); tcs.TrySetResult(e); } ); eventInfo.AddEventHandler(eventSource, eventHandler); return tcs.Task; } }
Man, I can't upvote this enough! Awesome, as good as it get, love it! :-D
A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
-
Man, I can't upvote this enough! Awesome, as good as it get, love it! :-D
A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
-
Not sure where to post that, (there might some sort of MSDN link somewhere) for now I just post there. "Sometimes" one has to wait for an event to be triggered (once) and then do something, I'd like to write a
WaitForEvent()
method. Unfortunately, due to the particular of event syntax, I can't and I have to write one wait for *that* event method for every single event I am interested in!... :(( Mmm... case for a code sinppet me just think! :omg: :-\ :rolleyes: In any case here is the syntax for a specific event:Task WaitForThatEventAsync(Foo source)
{
var res = new TaskCompletionSource<bool>();
EventHandler eh = null;
eh = (o, e) =>
{
source.ThatEvent -= eh;
res.TrySetResult(true);
};
source.ThatEvent += eh;
return res.Task;
}EDIT My explanation seem confusing.. another explanation is that I would like to be able to write a "general purpose"
WaitForEvent()
extension method that transform this cluncky codeEventHandler ev = null;
ev = (o, e) => {
source.Event -= eh;
DoSomething();
};
source.Event += eh;into this elegant code
await source.Event.WaitForEvent()
DoSomething();where both do the exact same thing! Sadly this is not possible right now... I have a to write a new
WaitForThatEvent()
method for each event I am interested in... :(( but it would be cool. Would make ReactiveC# better looking too.A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
your prince code will come and rescue you someday ;P
-
your prince code will come and rescue you someday ;P
It already had!! :omg: :-\ The Lounge[^]
A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!