Custom keywords and compiler-supplied code

J

Jon

I'm investiging multi-threaded GUI applications; specifically the
technique used to ensure that controls are only modified under the
correct thread. The standard technique is to use

if(InvokeRequired == true) ... BeginInvoke(...) ...

I have some code that ensures that an event fired from a worker
(non-GUI) thread will use the appropriate BeginInvoke call for
synchronisation. By offloading the synchronisation onto the worker
thread the GUI event handlers can be written safe in the knowledge that
they will -only- be called from the correct thread. This leaves the GUI
code a lot more focussed and less cluttered, etc.

However, what I'd really like to do is create my own custom C# keyword,
say thread_safe_delegate, (ignore non-standard naming conventions -
this is for illusation only). I'd like the compiler to process this in
much the same way as it does with the delegate keyword. (I.e. emit code
into the assembly to produce a private and embedded class; ideally the
intellisense system should also be able to pick up on this).

The end result would be that I could declare a GUI-safe event something
like this..

thread_safe_delegate void MyDelegate(int i);
event MyDelegate myEvent;

The technique I use in my code (mentioned above) for synchronisation is
to provide to my worker thread with a synchronisation GUI object, for
example:

Control eventSync;

Given the thread-safe delegate, an event, and a synchronisation object,
I would then be able to say...

void Test(int x)
{
myEvent(eventSync, x);
}

The compiler-generated delegate class would take care of invoking the
event handler(s) either directly (when the caller is on the GUI thread)
or asynchronously (using BeginInvoke when on a worker thread).

So.. the questions are:
1. Is it possible to define a new keyword and the code it should emit?
2. Could intellisense be made aware of this?
3. Is the C# compiler's support for the delegate keyword hard-coded or
part of a more customisable framework?
4. Does anyone know how the runtime resolves methods of
compiler-supplied delegate classes (specifically the Invoke and
BeginInvoke methods which appear 'stubbed-out' in the generated IL)?

Any feedback appreciated,
Jon.
 
N

Nicholas Paldino [.NET/C# MVP]

Jon,

Quite simply, none of what you want to do is possible. The compiler, as
well as VS just simply don't have what you want.

However, you can write a snippet in VS.NET 2005 which will expand to the
code that you want.

Also, in .NET 2.0, you can create a method which will simplify what you
are trying to do, using anonymous delegates.

Basically, you would have something like this:

static object SafeInvoke(ISynchronizeInvoke o, MethodInvoker methodInvoker)
{
// Check to see if invoking.
if (o.InvokeRequired)
{
return o.Invoke(methodInvoker, null);
}
else
{
return methodInvoker.DynamicInvoke(null);
}
}

Then, you can call it like this:

static void Main(string[] args)
{
SafeInvoke(null,
delegate()
{
return null;
});
}

You would replace the anonymous delegate with your code. You don't have
to worry about parameters, since you can use whatever state is on the stack
in the anonymous delegate code.

As for the runtime resolving the delegate code, I would assume that it
simply looks at the Method that is attached to it, and invokes it.

Hope this helps.
 
J

Jon

Nicholas - thanks for the response.

I've already written code described in my first post. As an example,
instead of calling...

evOnTick(this, eventArgs);

I can call...

GUIAwareEvents.Fire(eventSync, evOnTick, new object[] { this, eventArgs
});

where...
- GUIAwareEvents.Fire is a static method on a helper class;
- eventSync is a Control to synchronise against;
- evOnTick is the event to call;
- the third parameter is the array of args to pass to the event.

The great thing with this is that only a small modification is requred
to the code that fires the event (which almost satisfies my
requirements).

But there are two downsides... there is no compile-time type checking
of the argument list (which is also true for any late-bound
invocation); and secondly because my helper class uses late bound calls
(DynamicInvoke and BeginInvoke) there is a speed hit.

The whole purpose of this is to have simpler to read code.

Also.. regarding your code sample.. I'm not sure I get the reason for
it. all I want is to change a standard event / event-handler into
something that's GUI-thread safe, with minimal changes. The GUI side
should look like normal event handling (i.e. can assume its under the
GUI thread). The threading side shouldn't need to explicitly examine
the sync object - it should delegate to some more generic code.

If you have any more info on how you think anonymous delegates would
help with this please post.

Thanks,
Jon.
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Jon,

So.. the questions are:
1. Is it possible to define a new keyword and the code it should emit?

No, This is the language that the compiler understands. You cannot extend
the language, unless you build your own compiler and probably call your
language something else. I believe since C# is standardized language if you
altered you cannot call it C# anymore.

I read some column in some of the magazines about a new Microsof project
code name "Phoenix" (http://research.microsoft.com/phoenix/). If one day
this gets released it could be possible to do something like this
attributing your delegates.

I don't know way you want to alter the language. I think is as good as it
is. C# is OO language and .NET is OO framework, why you don't just create a
class that will take care of this. The class should be pretty simple. Yes it
won't be like part of the language, but this is shouldn't be a big deal.

Here is some sample that I jotted down:
public sealed class SyncDelegate<T>
{

private ISynchronizeInvoke syncObject;
private Delegate internalDelegate;

private SyncDelegate(ISynchronizeInvoke sync, Delegate
handlerDelegate)
{
syncObject = sync;
this.internalDelegate = handlerDelegate;
}
private void Handler(object sender, T e)
{
// Marshaling the event handler call in the UI thread.
this.syncObject.Invoke(internalDelegate, new object[] { sender,
e });

}public sealed class SyncDelegate<T>
{

private ISynchronizeInvoke syncObject;
private Delegate internalDelegate;

private SyncDelegate(ISynchronizeInvoke sync, Delegate
handlerDelegate)
{
syncObject = sync;
this.internalDelegate = handlerDelegate;
}
private void Handler(object sender, T e)
{
// Marshaling the event handler call in the UI thread.
this.syncObject.Invoke(internalDelegate, new object[] { sender,
e });

}

public static Delegate Create(ISynchronizeInvoke sync, Delegate
handlerDelegate)
{
SyncDelegate<T> syncDel = new SyncDelegate<T>(sync,
handlerDelegate);
return Delegate.CreateDelegate(handlerDelegate.GetType(),
syncDel, "Handler");

}

}

public static Delegate Create(ISynchronizeInvoke sync, Delegate
handlerDelegate)
{
SyncDelegate<T> syncDel = new SyncDelegate<T>(sync,
handlerDelegate);
return Delegate.CreateDelegate(handlerDelegate.GetType(),
syncDel, "Handler");

}

}

and here is how you use it:
Assuming that you want to handle an event declared as EventHandler and you
want to marshal the call to the UI thread that created *form*

someObj.MyEvent += (EventHandler)SyncDelegate<EventArgs>.Create(form, new
EventHandler(DoMyEvent));

Yes it is not as beautiful as couple of new keywords, but it still works and
is language independent.
3. Is the C# compiler's support for the delegate keyword hard-coded or
part of a more customisable framework?

It is not hard-coded per se it is language keyword and as such is well
defined, documented and standardized.
..
4. Does anyone know how the runtime resolves methods of
compiler-supplied delegate classes (specifically the Invoke and
BeginInvoke methods which appear 'stubbed-out' in the > generated IL)?

I suppose you are talking Control.Invoke and BeginInvoke. They both use the
message queue and window messages to marshal the call.
The same technique is used with ActiveX controls created in STA threads.

However, I find interesting that you brought up this question. We are all
reading about the new exiting technologies that Microsoft talk about such as
LINQ, CCR (Concurrency and Coordination Runtime). Everything sounds really
good and powerful no doubt bout it. Very often they talk about integrating
this into the language, by introducing new keywords and language constructs
and we should probably be anxious to have these new languages that will make
our programming life easier.

The other day I read Charles Petzold's speech "Does Visual Studio Rot the
Mind?". There he gives some stats about .Net 2.0 having only in the system
assemblies 5,000 public classes that include over 45,000 public methods and
15,000 public properties. His idea is that there are no more programmers
that know everything and the programmers now specialize in some part of the
framework. This is normal for a framework or a platform, but now we are
talking about extending the language with new constructions and keywords.
Who wants language with 5000 keywords? Is it going to make our life easier?
Won't those new technologies be better off as part of the framework?

I really hope that all these talks about extending the language are said to
make us believe that the new stuff is so cool and powerful that they even
could be integrated in the language, but actually they won't do it and they'll
live them in the framework where their place is.
 
J

Jon

Hi - thanks for the responses.

Just a few final thoughts...

1. Having to sprinkle GUI code with InvokeRequired tests means the GUI
looses focus. Also, a third-party control may not have thread-awareness
built into its event handlers. Therefore if you wired a threaded event
to it you'd have a problem. Making the threaded code have optional
synchronisation on its event-firing is one good way to alleviate this.

2. By not having the ability to have customised compiler-generated code
all of the fully generic solutions require the use of
ISynchronizeInvoke.Invoke or Delegate.DynamicInvoke, etc. These are all
late-bound calls and are significantly slower than calling a delegate
directly. I.e. the C# compiler and JIT compiler between them have
features that cannot be exploited by an end-programmer. I 100% agree
that keyword bloat is bad - I'm not asking for that. What I want is
some way to emulate the compiler's ability to inject code and have
intellisense pick it up.

3. Because C# generics are supported by the run-time (whereas C++
templates are processed at compile-time), it is not possible to exploit
them fully to solve this problem. I.e. a generic method cannot get
access to a compiler-supplied Invoke method on a delegate, only the
DynamicInvoke method which of course is late-bound and slow.

4. Regarding the runtime handling of a delegate's Invoke method, I was
referring to the following IL example:

..method public hidebysig newslot virtual
instance int32 Invoke(int32 a,
int32 b) runtime managed
{
} // end of method MyDelegate::Invoke

[This is generated from "public delegate int MyDelegate(int a, int
b);"]

I was wondering what the JIT compiler does with this - out of
curiousity :)

As a very final comment, here is a sample of code (from my threading
class) I'm now using in my test application. This allows the event to
be used directly if a synchronous call can be made, otherwise an
asynchronous call is made.

Note: evOnTick is an event, eventSync is of type ISynchronizeInvoke.

if (evOnTick != null)
{
if ((eventSync == null) ||
(eventSync.InvokeRequired == false))
{
// fast and direct call to the handler
evOnTick(this, eventArgs);
}
else
{
// asychronous call, slow but safe!
eventSync.BeginInvoke(evOnTick, new object[] {
this, eventArgs });
}
}

Thanks again for feedback,
Jon.
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Jon,

1. Having to sprinkle GUI code with InvokeRequired tests means the GUI
looses focus. Also, a third-party control may not have thread-awareness
built into its event handlers. Therefore if you wired a threaded event
to it you'd have a problem. Making the threaded code have optional
synchronisation on its event-firing is one good way to alleviate this.

I know what you mean. Though, keep in mind that .NET is designed to be
platform independent. On the other hand Windows Forms is not.
This all Control.Invoke and the need to marshal execution in the UI thread
comes from the Windows OS and its message management system.
Delegates are not part of windwos forms though.When one declares events one
cannot know how the event is going to be handled and processed.
For example I can have a code that executes in a worker thread and this code
fires an event. I handle that event in some class (not a control at all)
then call some method that calls another method and so on and at some point
it just happens that one of the method in the chain of calls sets a property
of a control. And all this happens in a worker thread.

The object firing the event does not know who is going to handle it. This
the whole point and beauty of the Observer design pattern.
The only place where the syncronization can happen is in the event handler.
The event handler is the only one that knows if the call needs to marshaled
or not.

As far as it goes for a thrid-party controls itis very unlikely to happen.
Usually controls fire events, they don't handle.If they do they handle
events from known sources and whoever wrote the control should take into
account the possibility of the event to be firead from a different thread.
If some other code calls methods or sets/gets properties of the control
this code has to make sure that the call is executed by the UI thread.

3. Because C# generics are supported by the run-time (whereas C++
templates are processed at compile-time), it is not possible to exploit
them fully to solve this problem. I.e. a generic method cannot get
access to a compiler-supplied Invoke method on a delegate, only the
DynamicInvoke method which of course is late-bound and slow.

Yes, generic delgates and non-generic delegates are different objects event
though the signatures are the same. The same would happen if you decalare
two non-generic delegates with the same signature. They are just different
types. Never tried but I'm pretty sure the same would happen with C++
templates. Even thought they are solved at compile time the generated types
are different.
4. Regarding the runtime handling of a delegate's Invoke method, I was
referring to the following IL example:

.method public hidebysig newslot virtual
instance int32 Invoke(int32 a,
int32 b) runtime managed
{
} // end of method MyDelegate::Invoke
I was wondering what the JIT compiler does with this - out of
curiousity :)


It is a simple call to the list of target methods. I'm not sure (never try
to benchmark), but I don't think DynamicInvole will be big time slower than
normal invoke.>
As a very final comment, here is a sample of code (from my threading
class) I'm now using in my test application. This allows the event to
be used directly if a synchronous call can be made, otherwise an
asynchronous call is made.

Note: evOnTick is an event, eventSync is of type ISynchronizeInvoke.

if (evOnTick != null)
{
if ((eventSync == null) ||
(eventSync.InvokeRequired == false))
{
// fast and direct call to the handler
evOnTick(this, eventArgs);
}
else
{
// asychronous call, slow but safe!
eventSync.BeginInvoke(evOnTick, new object[] {
this, eventArgs });
}
}


I still believe the handler should take care of this not the sender of the
event. Even though there is one example in the framework that the sender
takes care of the thread switching - System.Timers.Timer and this is the
only one that I know..
 
J

Jon

Stoitcho - hi...

Couple of comments...

DynamicInvoke is hugely slower than a direct invocation, because it
must use run-time reflection to do parameter verification and argument
passing. On a test I ran earlier this was shown to be several hundred
times slower than direct invocation.

Re the implementation of the Invoke method, I know that it invokes the
target methods. The thing I am curious about is at what point does the
JIT patch up the implementation (since the IL assembly has no
implementation of any delegate's Invoke methods)?

Although many GUI controls and forms normally only get hit from their
primary thread there are many occasions when third-party components and
controls utilise threads and fire events from these threads. As an
example, I'm currently working with some SNMP protocol components. One
mode of operation uses asynchronous SNMP messages. The components fires
results back to an observer but using its own thread (for asynchronous
mode). The clever thing that the component writers have done is to add
an "InvokeThrough" property. So when I add their component to my form I
set the form as the InvokeThrough property - then when the control has
to fire events from worker threads it uses the InvokeThrough to ensure
synchronisation with my form. This means my form will happily work
(unchanged) for both sync. and async. SNMP operations. This is a
beautifully sweet feature since with only one property to set I can
safely support both operations without having to write any code or
worry about threads. This is an example of a component writer that has
considered the end-user early on and provided simple and elegent
solutions to the potential problems. That's the sort of thing I'm
after.

Jon.
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Jon,

This is a
beautifully sweet feature since with only one property to set I can
safely support both operations without having to write any code or
worry about threads. This is an example of a component writer that has
considered the end-user early on and provided simple and elegent
solutions to the potential problems. That's the sort of thing I'm
after.

Yes, it is indeed and you have all the tools to do it. I don't see to be
necessary for the .NET framework or languages to provide support out of the
box. At the very end only Windows Forms controls (not componets) have
problems with multithread execution. Don't forget that .NET and C# is not
all about Windows Forms :)

This is just my thoughts. At the same time I see your point. It wold be
defintely easier if we could declare events and let the runtime make the
correct decission whether to marshal the call or not.
 
J

Jon Skeet [C# MVP]

Stoitcho Goutsev (100) said:
Yes, it is indeed and you have all the tools to do it. I don't see to be
necessary for the .NET framework or languages to provide support out of the
box. At the very end only Windows Forms controls (not componets) have
problems with multithread execution. Don't forget that .NET and C# is not
all about Windows Forms :)

This is just my thoughts. At the same time I see your point. It wold be
defintely easier if we could declare events and let the runtime make the
correct decission whether to marshal the call or not.

I've not been following this thread particularly closely, but this
feels very much like the kind of thing AOP is good for. I'm hoping
Anders is considering AOP for C# 4.0...
 
J

Jon

Hi - I feel I should clarify a point here... I'm totally not proposing
that MS should provide me with a new keyword to do this. What I'm
interesting in is the ability to write bespoke code that I can somehow
have processed in a similar way to that of delegates. It's no small
revolation when you first discover that the C# compiler takes a simple
delegate declaration and from there provides a hidden class (and one
that is derived from an otherwise un-derivable base,
MulticastDelegate!!!), and also gets intellisense to use this.

As far AOP - I must confess I currently know very little about aspects
and weaving, etc. But this is on my current list of things to learn,
including DSL.

There's so much to learn and so little time - c'est la vie!

Jon.
 
J

Jon Skeet [C# MVP]

Jon said:
Hi - I feel I should clarify a point here... I'm totally not proposing
that MS should provide me with a new keyword to do this. What I'm
interesting in is the ability to write bespoke code that I can somehow
have processed in a similar way to that of delegates. It's no small
revolation when you first discover that the C# compiler takes a simple
delegate declaration and from there provides a hidden class (and one
that is derived from an otherwise un-derivable base,
MulticastDelegate!!!), and also gets intellisense to use this.

As far AOP - I must confess I currently know very little about aspects
and weaving, etc. But this is on my current list of things to learn,
including DSL.

There's so much to learn and so little time - c'est la vie!

It sounds to me like AOP is exactly the kind of thing you're after -
it's all about making it really easy to execute a bit of code in
various different places. I don't know much about it myself, to be
honest, but the little bit I've used it has been *really* handy. AOP
and design by contract are areas I really hope C# at least looks at
closely for future versions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top