自定义关键字和编译器提供的代码 [英] Custom keywords and compiler-supplied code

查看:85
本文介绍了自定义关键字和编译器提供的代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究多线程GUI应用程序;特别是

技术用于确保控件仅在

正确的线程下修改。标准技术是使用


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


我有一些代码可以确保从工作人员触发的事件

(非GUI)线程将使用适当的BeginInvoke调用来进行

同步。通过将同步卸载到worker

线程上,可以安全地编写GUI事件处理程序,因为它们只能从正确的线程中调用它们。这使得GUI

代码更加专注,不那么杂乱等等。


但是,我真正想做的就是创建自己的代码自定义C#关键字,

说thread_safe_delegate,(忽略非标准命名约定 -

这仅用于幻觉)。我希望编译器在

中处理它,就像使用delegate关键字一样。 (即将代码

发送到程序集中以生成私有和嵌入式类;理想情况下,

intellisense系统也应该能够接收到这一点。)


最终的结果是我可以声明一个GUI安全事件

像这样..


thread_safe_delegate void MyDelegate (int i);

事件MyDelegate myEvent;


我在我的代码中使用的技术(如上所述)用于同步是

为我的工作线程提供同步GUI对象,用于

示例:


控制eventSync;


给定线程安全委托,事件和同步对象,然后我就可以说...


void Test(int x)

{

myEvent(eventSync,x);

}


编译器 - 生成的委托类将直接调用

事件处理程序(当调用者在GUI上时)线程)

或异步(在工作线程上使用BeginInvoke)。


所以..问题是:

1是否可以定义一个新关键字及其应该发出的代码?

2.可以让intellisense意识到这一点吗?

3.是否是C#编译器''支持委托关键字硬编码或

更可定制框架的一部分?

4.有没有人知道运行时如何解决
$ b的方法$ b编译器提供的委托类(特别是Invoke和

BeginInvoke方法,它们在生成的IL中出现''stubbed-out''?


Any感谢反馈,

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.

推荐答案

Jon,


很简单,没有你想做的事情是可能的。编译器,和

以及VS只是根本没有你想要的东西。


但是,你可以在VS.NET 2005中编写一个片段这将扩展到你想要的

代码。


另外,在.NET 2.0中,你可以创建一个简化你的方法的方法。 >
正在尝试使用匿名代表。


基本上,你会有这样的东西:


静态对象SafeInvoke (ISynchronizeInvoke o,MethodInvoker methodInvoker)

{

//检查是否调用。

if(o.InvokeRequired)

{

return o.Invoke(methodInvoker,null);

}

else

{

返回methodInvoker.DynamicInvoke(null);

}

}


然后,你可以这样称呼:


static void Main(string [] args)

{

SafeInvoke(null,

委托()

{

返回null;

});

}


您将用您的代码替换匿名委托。你没有担心参数,因为你可以使用匿名代理代码中的任何状态



至于解析代理代码的运行时,我会假设它只是查看附加到它的方法,然后调用它。


希望这会有所帮助。


-

- Nicholas Paldino [.NET / C#MVP]

- < a href =mailto:mv*@spam.guard.caspershouse.com> mv*@spam.guard.caspershouse.com

" Jon" <乔*********** @ googlemail.com>在消息中写道

news:11 ********************** @ g49g2000cwa.googlegr oups.com ...
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.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Jon" <jo***********@googlemail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
我正在研究多线程GUI应用程序;特别是
技术,用于确保控件只在
正确的线程下修改。标准技术是使用

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

我有一些代码可以确保一个事件从工作人员解雇
(非GUI)线程将使用适当的BeginInvoke调用进行同步。通过将同步卸载到worker
线程上,可以安全地编写GUI事件处理程序,因为它们只能从正确的线程调用它们。这使得GUI
代码更加集中,不那么杂乱等等。

然而,我真正想做的是创建我自己的自定义C#关键字,
比如thread_safe_delegate,(忽略非标准的命名约定 -
这只是用于幻觉)。我希望编译器能够像处理delegate关键字一样处理它。 (即将代码发送到程序集中以生成私有和嵌入类;理想情况下,
intellisense系统也应该能够接受这个)。

最终结果将是是的,我可以声明这样的GUI安全事件
这样......

thread_safe_delegate void MyDelegate(int i);
事件MyDelegate myEvent;

我在我的代码(如上所述)中用于同步的技术是为我的工作线程提供同步GUI对象,例如:

控制eventSync;

鉴于线程安全的委托,事件和同步对象,我可以说...

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

编译器生成的委托类将负责调用
事件处理程序直接(当调用者在GUI线程上时)或异步(在工作线程上使用BeginInvoke)。

所以......问题是:
1.是否可以定义一个新的关键字及其应该发出的代码?
2.可以让intellisense意识到这一点吗?
3.是C#编译器吗?是否支持委托关键字硬编码或更可定制框架的一部分?
4.有没有人知道运行时如何解析编译器提供的委托类的方法(特别是Invoke)并且
BeginInvoke方法在生成的IL中显示为stubed-out?

任何反馈都赞赏,
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.



Nicholas - 感谢您的回复。


我已经编写了第一篇文章中描述的代码。例如,

而不是叫...


evOnTick(this,eventArgs);


我可以打电话给...


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

});


where ...

- GUIAwareEvents.Fire是辅助类上的静态方法;

- eventSync是一个要同步的控件;

- evOnTick是要调用的事件;

- 第三个参数是传递给事件的args数组。


这件事的好处是只需要一个小的修改就可以获得激活事件的代码(几乎满足我的

要求)。

但是有两个缺点...没有编译时类型检查

的参数列表(任何后期绑定也是如此

调用);其次因为我的助手类使用后期绑定调用

(DynamicInvoke和BeginInvoke)有一个速度命中。


这个的全部目的是为了更简单阅读代码。


另外..关于你的代码示例..我不确定我得到了

的原因。我想要的是将标准的事件/事件处理程序更改为

,这是一个GUI线程安全的东西,只需要很少的更改。 GUI端

应该看起来像正常事件处理(即可以假设它在

GUI线程下)。线程方不需要明确检查同步对象 - 它应该委托给一些更通用的代码。


如果您还有其他信息关于你如何看待匿名代表将

帮助这个请发帖。


谢谢,

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.


Jon,

Jon,

所以..问题是:
1.是否可以定义一个新的关键字和它应该发出的代码?


否,这是编译器理解的语言。你不能扩展

这个语言,除非你建立自己的编译器,并且可能会用你的

语言。我相信,因为C#是标准化的语言,如果你改变了b $ b,你再也不能称之为C#了。


我读了一些关于新的微软杂志的专栏项目

代码名称" Phoenix" ( http://research.microsoft.com/phoenix/) 。如果有一天

这个被释放了,就有可能做这样的事情

归因于你的代表。


我不喜欢不知道你想改变语言的方式。我觉得和它一样好。

是。 C#是OO语言,.NET是OO框架,为什么你不只是创建一个

类来处理这个问题。这堂课应该很简单。是的它

不会成为语言的一部分,但这不应该是一个大问题。


这里有一些样本我记下了:

公共密封类SyncDelegate< T>

{


私有ISynchronizeInvoke syncObject;

private Delegate internalDelegate;


private SyncDelegate(ISynchronizeInvoke sync,Delegate

handlerDelegate)

{

syncObject = sync;

this.internalDelegate = handlerDelegate;

}

private void Handler(对象发送者,T e)

{

//在UI线程中对事件处理程序调用进行封送。

this.syncObject.Invoke(internalDelegate,new object [] {sender,< br $>
e});


}公共密封类SyncDelegate< T>

{


private ISynchronizeInvoke syncObject;

private Delegate internalDelegate;


handlerDelegate)

{

syncObject = sync;

this.internalDelegate = handlerDelegate;

}

private void Handler(对象发送者,T e)

{

//在UI中封送事件处理程序调用线程。

this.syncObject.Invoke(internalDelegate,new object [] {sender,

e});


}


public static Delegate Create(ISynchronizeInvoke sync,Delegate

handlerDelegate)

{

SyncDelegate< T> ; syncDel = new SyncDelegate< T>(sync,

handlerDelegate);

返回Delegate.CreateDelegate(handlerDelegate.GetType(),

syncDel, 处理程序;


}


}


public static Delegate Create(ISynchronizeInvoke同步,代表

handlerDelegate)

{

SyncDelegate< T> syncDel = new SyncDelegate< T>(sync,

handlerDelegate);

返回Delegate.CreateDelegate(handlerDelegate.GetType(),

syncDel, Handler);


}


}


以下是您的使用方法它:

假设您想要处理一个声明为EventHandler的事件,并且您想要编组对创建* form *
<的UI线程的调用br />
someObj.MyEvent + =(EventHandler)SyncDelegate< EventArgs> .Create(form,new

EventHandler(DoMyEvent));


是的,它不像几个新关键字那么漂亮,但它仍然可以工作,而且b $ b与语言无关。 3. C#编译器是否支持委托关键字硬编码或更可定制框架的一部分?


它本身并不是硬编码的语言关键字,因此很好地定义,记录和标准化了


.. 4.有没有人知道运行时如何解析编译器提供的委托类的方法(特别是在>生成的IL中出现''stubbed-out''的Invoke和
BeginInvoke方法) ?


我想你正在谈论Control.Invoke和BeginInvoke。他们都使用

消息队列和窗口消息来编组调用。

在STA线程中创建的ActiveX控件使用相同的技术。

但是,我发现你提出这个问题很有趣。我们都在阅读有关微软谈论的新技术,例如:
LINQ,CCR(并发和协调运行时)。一切听起来真的很好。无论如何,b b b b b b b b b b b b b b b b b b b b b b他们经常谈论通过引入新的关键词和语言结构来将

这种语言整合到语言中,我们应该急于使用这些新的语言来制作这些语言。 />
我们的编程生活更轻松。


前几天我读了Charles Petzold的演讲是否Visual Studio烂了

Mind ?" ;.在那里,他提供了一些关于.Net 2.0的统计数据,只有在系统中。

汇编5,000个公共类,包括超过45,000个公共方法和

15,000个公共属性。他的想法是,没有更多的程序员知道所有内容,程序员现在专注于

框架的某些部分。这对于框架或平台来说是正常的,但现在我们讨论用新的结构和关键字扩展语言。

谁想要5000个关键字的语言?是否会让我们的生活更轻松?

难道这些新技术作为框架的一部分会变得更好吗?


我真的希望所有人这些关于扩展语言的讨论被称为

让我们相信新的东西是如此的酷和强大,他们甚至可以将b $ b整合到语言中,但实际上他们他们不会这样做,他们会在他们所处的框架中生活他们。


-

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.

--

Stoitcho Goutsev (100) [C# MVP] Any feedback appreciated,
Jon.



这篇关于自定义关键字和编译器提供的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆