0

阅读这篇文章,我发现了几种调用方法的方法。

调用方法:

public static void SendData(string value) { }

来电:

delegate void MyDelegate(string value);

//Slow method - NOT RECOMMENDED IN PRODUCTION!        
SendData("Update");

// Fast method - STRONGLY RECOMMENDED FOR PRODUCTION!
MyDelegate d = new MyDelegate(SendData);
d.BeginInvoke("Update", null, null);

这是真的吗?它更快吗?

Action send = () => Send("Update");
send();

或者也许这个?

我需要将一个方法调用到具有最高性能的 SQL CLR 触发器中,因此即使是很小的速度增加也是有意义的。

4

5 回答 5

20

哪个“更快”?

1)让鲍勃修剪你的草坪。等他说完。然后去商场。

2)让鲍勃修剪你的草坪。他正在修剪你的草坪时去商场。

第二种技术可以让你更快地到达商场。你付出的代价是你不知道你回家时草坪是否会被修剪。使用第一种技术,您知道当您从商场回家时,草坪将被修剪,因为您一直等到它在您离开之前。如果您的逻辑依赖于知道在您回来时草坪已被修剪,那么第二种技术是错误的。

现在重要的一点:显然,这两种技术都不能让你的草坪修剪得比另一种更快。 当你问“哪个更快?” 您必须指出您正在测量速度的操作。

于 2010-07-21T15:01:56.400 回答
13

使用委托并不比直接调用方法快(实际上,创建委托然后调用它会更昂贵)。

这看起来更快的原因是因为在方法运行时直接调用该方法会阻塞正在执行的线程。您的委托示例异步调用该方法(使用BeginInvoke),因此调用线程在执行该方法时继续执行。

此外,每当您在委托上调用 BeginInvoke 时,您还应该有相应的 EndInvoke,您在示例中缺少它:

EndInvoke() 是可选的,是可选的,还是绝对不是可选的?

IanG on Tap:EndInvoke 不是可选的

于 2010-07-21T14:52:28.530 回答
2

SendData从何时返回呼叫者 的角度来看,它是一种安慰剂速度改进。BeginInvoke将采用一个ThreadPool线程并在该线程上启动该方法,然后立即返回给调用者 - 实际工作在另一个线程上。无论线程处于何种状态,完成这项工作所需的时间都将保持不变。它可能会提高您的应用程序的响应能力,具体取决于工作,但委托并不比直接方法调用快 - 正如我所说,在您的情况下它似乎更快,因为它会立即返回。

试试这个:更改BeginInvokeInvoke- 调用者现在阻塞,与正常调用相同SendData

假设代码注释不是您的(即“推荐用于生产”),我会很快找到负责的开发人员,并确保他们知道Delegate.BeginInvoke并且他们正在使他们的应用程序在没有意识到的情况下成为多线程的事实......

要回答这个问题,直接方法调用总是最快的方法——委托或反射会产生开销。

于 2010-07-21T14:55:05.923 回答
1

提高性能的最佳机会是优化触发器将调用的 SQL CLR 存储过程中的方法中的代码。你能发布更多关于这方面的信息吗?

于 2010-07-21T14:59:10.890 回答
1

请注意,在您引用的文章中,作者谈论的是 WCF 调用,尤其是插入和更新数据库的调用。

在这种特定情况下需要注意的关键点是:

  • 这项工作正在由另一台机器完成。
  • 您得到的唯一信息是“成功!” (通常)或(偶尔)“失败”(作者似乎并不关心)

因此,在那种特定情况下,后台调用更好。对于一般用途,直接调用更好。

于 2010-07-21T15:58:31.710 回答