PLZ帮助我进行说明 [英] PLZ HELP ME EXPLAINING

查看:156
本文介绍了PLZ帮助我进行说明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法获得这部分

I cannot get this part

Delegate Function WaveInfoHandler(ByVal lLastx As Integer, ByVal lLastLeftY As Integer, ByVal lLastRightY As Integer, _ ByVal lx As Integer, ByVal ly As Integer, ByVal lEnd As Integer, ByVal lAbsSizeY As Integer, ByVal bRectangles As Boolean, ByVal lMidy As Integer) As WaveData 

Delegate Sub UpdateUIHandler(ByVal Statusmsg As String, ByVal result As WaveData) 

Private WaveInfo_handler As WaveInfoHandler = AddressOf WaveInfo 



:confused:



:confused:

Private WaveInfo_callback As AsyncCallback = AddressOf GetWaveInfo_callback 

:混淆:

Private Function WaveInfo(ByVal lLastx As Integer, ByVal lLastLeftY As Integer, ByVal lLastRightY As Integer, _ ByVal lx As Integer, ByVal ly As Integer, ByVal lEnd As Integer, ByVal lAbsSizeY As Integer, _ ByVal bRectangles As Boolean, ByVal lMidy As Integer) As WaveData

推荐答案

这实际上很简单.您需要了解使用委托所需的三个实际部分.另外,您必须了解,委托用于调用在编写本文时不知道实际代码的函数.一个很好的例子是一个事件,它也是一个委托类型.如果您有一个按钮并为其创建click事件处理程序,则这是您要填充特定代码的委托.

使用的三个部分:
-委托定义

对于按钮,定义说明该功能的第一个参数为Object sender,第二个参数为e as EventArgs.该定义实际上具有名称CommandEventHandler.在您的问题中,带有关键字委托的前两个也是实际的定义.第一个的名称例如是WaveInfoHandler.这可能看起来有些混乱,因为它看起来几乎像一个普通的函数定义,但是在这种情况下,名称WaveInfoHandler是实际的类型名称,而不是函数名称.委托关键字将解释方式从名称为WaveInfoHandler的函数"更改为名称为WaveInfoHandler的函数".

-占位符

这只是一个变量定义,可以保存具有与先前定义相同的布局的函数的地址.这样的函数的参数和返回类型必须完全适合,但是函数本身的名称可以随意命名. WaveInfo_handler就是您在问题中定义的占位符.

-实际功能的实现

实际的实现可以是您创建的功能.如前所述,函数实现必须具有与WaveInfoHandler定义相同的签名,以使其适合于占位符.如您所见,除了名称之外,WaveInfo函数与WaveInfoHandler的委托定义几乎完全相同.如您所知,此处的名称不相关,因此可以用该函数实现的地址填充占位符WaveInfo_handler.
It is actually kind of simple. You need to understand the three actual parts that are necessary for using delegates. Also, you must understand that delegates are used to call functions of which the actual code isn''t known at time of writing. A good example is an event, that is also a delegate type. If you have a button and create a click event handler for it, this is a delegate that you are filling with your specific code.

The three parts that used:
- delegate definition

For a button the definition stated that the functions first parameter is Object sender and the second is e as EventArgs. This definition actually has the name CommandEventHandler. In your question the first two with the keyword delegate are also the actual definitions. The name of the first is for example WaveInfoHandler. This may look a bit confusing, because it looks almost like a normal function definition, but in this case the name WaveInfoHandler is the actual type name instead of the function name. The delegate keyword changes the way of interpretation from "a function with the name WaveInfoHandler" to "a function definition with the name WaveInfoHandler".

- The placeholder

This is simply a variable definition that can hold the address of a function that has the same layout as defined earlier. The parameters and return type of such a function must fit exactly, but the name of the function itself is free to name it whatever you like. WaveInfo_handler is such a placeholder defined in your question.

- The actual function implementation

The actual implementation can be a function created by you. As told earlier, the function implementation must have the same signature of the WaveInfoHandler definition in order to fit it into the placeholder. As you can see, the WaveInfo function is almost exacly the same as the delegate definition of WaveInfoHandler except for the name. As you now know the name is not relevant here, making it possible to fill the placeholder WaveInfo_handler with the address of that function implementation.
Private WaveInfo_handler As WaveInfoHandler = AddressOf WaveInfo 



您可以有多个实现,并可以随时分配不同的功能地址.这意味着将调用当时分配的功能地址.调用此函数实现的代码在编写时不必知道实际的函数.这使它成为非常强大的类型,并且非常有用.

祝你好运!



You can have multiple implementations and assign a different function address whenever you like. This means that the assigned function address at that time is called. The code that is calling this function implementation didn''t have to know the actual function at the time of writing. This is making it a very powerful type and extremely useful.

Good luck!


有关调用的更多信息


我希望您会添加您放置的评论作为有关invoke的答案.但无论如何,这就是答案:-)
将其发布为另一个答案的原因是因为尝试添加它作为注释时出现错误(我认为是因为它的大小)



当线程想要更​​新用户界面时,这不能直接完成.这样做的主要原因是UI是事件驱动的.这意味着必须采取一些措施才能引起任何反应.负责UI(重涂,处理按钮单击等)的主程序循环通过重复调用OS等待消息.这是所谓的消息循环( http://msdn.microsoft.com/zh-cn/library/ms644936%28VS.85%29.aspx [
嗯,这是一些信息,但实际上是使用invoke来处理UI更新的主要原因之一.当您从主线程之外的其他线程更新UI时,实际的UI将不会更新,因为没有请求这样做,也没有触发任何实际的重画事件.除主线程外,还有多个线程可能正在进行屏幕更新,而没有任何同步.这不是例外,将引发异常.为了克服这个问题,应该在主线程的上下文"中进行实际的更改(您可以说上下文"是某个线程的工作区).这意味着必须使用一种机制,使您想要执行的实际代码被传输到主线程,并让该线程执行该机制.因为主线程在处理传入消息时陷入了困境,所以最简单的方法是简单地向它传递一条消息,这清楚表明我们希望它执行某些代码.为了最大程度地减少消息的大小和开销,我们不会向其发送我们想要执行的代码,而是使用前面刚刚讨论过的强大技巧……您可能已经猜到了委托".除了UI线程外,其他线程将发送一条消息,请求执行某个功能,该消息作为委托(函数地址)传递,带有一些必须传递给该函数的参数.该消息由主线程拾取,然后执行,一次仅处理一条消息,因此,即使有很多线程都向该主线程偶尔发送消息,这些线程也都被一个一个地处理. ,提供了一种非常不错的同步方法.

一些额外的信息:在.net中,您经常会遇到检查以查看是否确实需要调用.这是通过使用InvokeRequired进行检查来完成的.当然,这是为了防止它一遍又一遍地调用.大多数更新UI的线程为此具有特定的功能,该功能将检查是否需要调用,并在需要时自行调用.然后,该函数将由主线程调用,并且检查是否需要调用的检查结果将为false.然后可以安全地完成必要的屏幕更新.这样,该功能就可以在需要时自行提供屏幕更新和调用.当然,查看是否需要调用的检查只是比较当前线程(由GetCurrentThread获取)和主窗口线程(由GetWindowThreadProcessID获取),如果它们不相等,则需要调用.

还有另一种称为Pinvoke的调用.有关更多信息,我建议您查看以下链接:
使用平台调用 [
Extra information about Invoke


I would expect you would have added the comment you placed as answer about invoke. But here''s the answer anyway :-)
The reason this is posted as another answer is because I got an error when trying to add it as a comment (I think because of the size of it)



When a thread wants to update the user interface, this cannot be done directly. The main reason for that, is that the UI is event driven. Meaning that there must be some action to get any reaction. The main program loop that is responsible for the UI (repainting, handling button clicks, etc...) waits for a message by repeated calls to the OS. This is a so called message loop (http://msdn.microsoft.com/en-us/library/ms644936%28VS.85%29.aspx[^]) that helps receiving input in an efficient and generic way. This also a reason why you should use threads for intensive processing because the OS will report your application as "not responding" if you do not occasionally handle these messages.

Well, this is some information aside but actual one of the main reasons why invoke is used for handling UI updates. When you would update the UI from another thread than the main thread, the actual UI would not be updated because there was no request to do this and no actual repaint event was fired. It also would be possible that multiple threads besides the main thread are doing screen updates without any synchronization what so ever. This is not excepted and will throw an exception. To overcome this, the actual change should be made in the "context" of the main thread (You could say that "context" is the workplace of a certain thread). This means that a mechanism must be used, in such a way that the actual code you would like to be executed, get transfered to the main thread and let that thread execute it. Because the main thread is caught up in handling incoming messages, the most easy way is to simply pass it a message which makes it clear that we would like it to execute certain code. To minimize the size of the message and overhead we don''t send it the code we would like to execute, but use an powerful trick that was just discussed earlier... as you might already guess "delegates". A thread, other than the UI thread, will send a message with the request to execute a certain function, that was passed as delegate (function address) with some parameters that must be passed to that function. This messages is picked up by the main thread and then executed, which handles only one message at a time, so even if there are a lot of threads that are all sending an occasional message to the main thread, these are each handled one by one, providing a very nice method of synchronization.

Some extra info: In .net you will often encounter a check to see if invoke is actually necessary. This is done by a check using InvokeRequired. This is of course to prevent it from invoking over and over again. Most threads that update the UI have a specific function for this that will check if invoke is required and invoke themselves if this is needed. The function will then be called by the main thread and the outcome of the check to see if invoke is required will be false. The necessary screen updating can then be done safely. This way the function is providing screen updating and invocation when necessary all by itself. Of course the check to see if invoke is required is simply to compare the current thread (obtained by GetCurrentThread) and the main window thread (obtained by GetWindowThreadProcessID) and if these are not equal an invoke is required.

There is also another type of invocation called Pinvoke. For more information on that I would recommend checking out the following link:
Using Platform Invoke[^]

Hopefully this gave you a good idea about invoke.


这篇关于PLZ帮助我进行说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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