异步调用 void 方法的最简洁方法

发布于 2024-07-27 00:49:20 字数 267 浏览 8 评论 0原文

我有一个我想异步调用的方法:

void Foo()
{
}

我确实可以通过以下方式异步调用它:

delegate void DVoidMethod();
DVoidMethod FooDelegate = new DVoidMethod(Foo);
FooDelegate.BeginInvoke(null,null);

有人有其他选择吗?

我觉得三行代码太多了?

I have a method which I would like to invoke asynchronously:

void Foo()
{
}

I can indeed invoke this asynchronously by the following:

delegate void DVoidMethod();
DVoidMethod FooDelegate = new DVoidMethod(Foo);
FooDelegate.BeginInvoke(null,null);

Has anyone got any alternatives?

I think three lines of code is too much?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

深海不蓝 2024-08-03 00:49:20

免责声明:

不要在实际代码中使用它。 这只是尝试缩短提到的代码 OP。 要执行真正的异步调用而不返回结果,请使用:

ThreadPool.QueueUserWorkItem(stateObject => Foo());

在框架中使用 ActionFunc 委托:

new Action(Foo).BeginInvoke(null, null);

Action从2.0开始就已经存在了。 3.5 中添加了其他变体。 然而,在 2.0 上,您可以在某处手动声明一堆它们以供进一步使用; 或者更好的是,使用 LINQBridge

Disclaimer:

Don't use this in real code. This is just an attempt to shorten the code OP mentioned. To do real async calls without getting results back, use:

ThreadPool.QueueUserWorkItem(stateObject => Foo());

Use Action and Func delegates in the framework:

new Action(Foo).BeginInvoke(null, null);

Action<T> has been around since 2.0. Other variants are added in 3.5. On 2.0, you can, however, declare a bunch of them somewhere manually for further use; or even better, use LINQBridge.

老街孤人 2024-08-03 00:49:20

怎么样:

ThreadPool.QueueUserWorkItem(new WaitCallback((o) => Foo()));

更新以考虑较新版本的.net中可用的TPL API:

.Net 4及更高版本中,您可以执行以下操作:

Task.Factory.StartNew(() => Foo());

.Net 4.5< /strong> 及以上您还可以执行以下操作:

Task.Run(() => Foo());

Task.Factory.StartNewTask.Run 的优点是“StartNew”方法有一些附加参数,可让您传递状态、任务创建选项和调度程序,以便在需要时为您提供一些额外的控制。

How about:

ThreadPool.QueueUserWorkItem(new WaitCallback((o) => Foo()));

Update to account for the TPL APIs available in newer versions of .net:

In .Net 4 and above you can do:

Task.Factory.StartNew(() => Foo());

In .Net 4.5 and above you can also do:

Task.Run(() => Foo());

The difference between Task.Factory.StartNew and Task.Run is that the 'StartNew' method has some additional parameters that let you pass state, task creation options and a scheduler to give you some extra control if you need it.

迎风吟唱 2024-08-03 00:49:20

您可以将其缩减为两行(在 .Net 1.1 及更早版本中):

delegate void DVoidMethod();
new FooDelegate(DVoidMethod).BeginInvoke(null, null)

但在 2.0 及更高版本中.. Mehrdad 的语法有效。

请参阅 MSDN 上的 2.0 及更高版本的操作委托:

http://msdn.microsoft.com/en-us/library/018hxwa8(VS.80).aspx

You can knock it down to two lines (in .Net 1.1 and earlier) with simply:

delegate void DVoidMethod();
new FooDelegate(DVoidMethod).BeginInvoke(null, null)

But in the 2.0 and later versions.. the syntax from Mehrdad works.

Refer to the Action delegate for 2.0 and later at MSDN at:

http://msdn.microsoft.com/en-us/library/018hxwa8(VS.80).aspx

远山浅 2024-08-03 00:49:20

如果不使用 Action 和 Func,您可以在 void () 委托的情况下使用 MethodInvoker:

new MethodInvoker(Foo).BeginInvoke(null, null);

另外,应该注意的是,如果您使用 BeginInvoke 方法,则必须在委托完成执行时调用 EndInvoke。所以上面的这一行必须更改为使用回调,或者您需要保留对委托的引用。就像这样:

MethodInvoker mi = null;
IAsyncResult ar = null;

ar = (mi = new MethodInvoker(Foo)).BeginInvoke(null,null);


.. sometime later after the delegate has completed executing
mi.EndInvoke(ar);

每当您使用 BeginInvoke 时都是如此。 所以我想最后我不会推荐使用 BeginInvoke 方法。

在我看来,@Steven 的解决方案使用 ThreadPool 是一个更好的解决方案..而且他显然:)

Without using Action and Func you could use the MethodInvoker in the case of the void () delegate:

new MethodInvoker(Foo).BeginInvoke(null, null);

Also, it should be noted that if you use the BeginInvoke method you have to call EndInvoke when the delegate has completed execution.. so this line above will have to change to either use a callback or you need to keep a reference to the delegate.. Like so:

MethodInvoker mi = null;
IAsyncResult ar = null;

ar = (mi = new MethodInvoker(Foo)).BeginInvoke(null,null);


.. sometime later after the delegate has completed executing
mi.EndInvoke(ar);

This is true whenever you use BeginInvoke. So I guess in the end I wouldn't recommend using the BeginInvoke method..

@Steven's solution using the ThreadPool is a much better solution in my opinion.. and his oviously:)

浪菊怪哟 2024-08-03 00:49:20

严格来说,从性能角度来看,我不会担心某些代码的行数,因为您不知道您所调用的函数背后有多少实际代码。

Strictly speaking I wouldn't worry about the number of lines of code something takes from a performance perspective because you have no idea how much actual code is behind the functions you're calling.

是你 2024-08-03 00:49:20

旧线程,但我无法抗拒堆积。

您确实必须调用 EndInvoke 以避免泄漏,即使您没有使用结果或对方法的完成做出反应。 但这并不意味着它一定是丑陋的。

BeginInvoke 需要 AsyncCallback 作为回调参数。 AsyncCallback 的签名是一个带有 IAsyncResult 的 void。 EndInvoke 具有该签名,因此:

    //waste some time...
    void Foo() {}
    void InvokeFoo()
    {
        Action fooer = () => Foo();
        fooer.BeginInvoke(fooer.EndInvoke, null);            
    }
    void InvokeFoo2()
    {
        // or, less concise but some consider more readable:
        Action fooer = new Action(Foo); //...invoke doesn't change
    }

Old thread, but I couldn't resist piling on.

You indeed must call EndInvoke to avoid leaks, even if you're not using the result or reacting to the method's completion. But that doesn't mean it has to be ugly.

BeginInvoke expects an AsyncCallback as the callback parameter. An AsyncCallback's signature is a void that takes an IAsyncResult. EndInvoke has that signature, so:

    //waste some time...
    void Foo() {}
    void InvokeFoo()
    {
        Action fooer = () => Foo();
        fooer.BeginInvoke(fooer.EndInvoke, null);            
    }
    void InvokeFoo2()
    {
        // or, less concise but some consider more readable:
        Action fooer = new Action(Foo); //...invoke doesn't change
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文