为什么';这个C#4.0异步方法不会被调用吗?

为什么';这个C#4.0异步方法不会被调用吗?,c#,asynchronous,action,begininvoke,C#,Asynchronous,Action,Begininvoke,我正在尝试编写一段非常简单的异步代码。我有一个void方法,它不接受任何参数,这是从Windows服务调用的。我想异步启动它,这样服务就不必等待方法完成 我创建了一个非常简单的测试应用程序,以确保编码正确,但没有调用异步方法。有人知道我做错了什么吗?顺便说一下,我使用的是.NET4.0,所以我不能使用wait(这会简单得多!) 这是我的全部测试样本 using System; using System.Threading; namespace AsyncCallback { interna

我正在尝试编写一段非常简单的异步代码。我有一个void方法,它不接受任何参数,这是从Windows服务调用的。我想异步启动它,这样服务就不必等待方法完成

我创建了一个非常简单的测试应用程序,以确保编码正确,但没有调用异步方法。有人知道我做错了什么吗?顺便说一下,我使用的是.NET4.0,所以我不能使用wait(这会简单得多!)

这是我的全部测试样本

using System;
using System.Threading;

namespace AsyncCallback {
  internal class Program {
    private static void Main(string[] args) {
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff to be done");
      new Action(DoStuff).BeginInvoke(ar => StuffDone(), null);
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done");
    }

    private static void StuffDone() {
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
    }

    private static void DoStuff() {
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Starting to do stuff");
      Thread.Sleep(1000);
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Ending doing stuff");
    }
  }
}

感谢您提供的帮助。

线程池中部署异步方法之前,您的程序将终止。让你的程序打开一点。可能
Console.ReadKey()
Main

的末尾,只要没有未完成执行的前台线程,任何应用程序都将立即结束。如果有任何后台线程,它们将不会保持进程“活动”

因为您在后台启动异步任务,并且没有任何东西可以保持前台线程运行,所以整个进程正在退出


您或者需要在前台线程中运行异步任务(据我所知,
BeginInvoke
无法完成,您需要显式创建一个新的
线程),或者执行其他操作来阻止主线程,直到它完成。

您没有等待完成,所以请尝试类似的操作

 Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff  to be done");
 var a = new Action(DoStuff);
 var iar = a.BeginInvoke(ar => StuffDone(), null);
 a.EndInvoke(iar);
 Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done");

首先,您的回调不是正确的委托。。。应该是

public delegate void AsyncCallback(IAsyncResult ar);
你的是

private static void StuffDone()
只需将其更改为以下内容:

private static void StuffDone(IAsyncResult ar){}
Action d = new Action(DoStuff);
d.BeginInvoke(StuffDone, d);
然后在您的回调中,确保通过调用

EndInvoke
异步状态上

像这样:

private static void StuffDone(IAsyncResult ar)
{
    Action r = ar.AsyncState as Action;
    r.EndInvoke(ar);

    Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
}
您需要做的另一个更改是,在主函数中实例化操作时,将操作本身作为
BeginInvoke
方法的“object”参数传递,如下所示:

private static void StuffDone(IAsyncResult ar){}
Action d = new Action(DoStuff);
d.BeginInvoke(StuffDone, d);

这应该可以解决你的问题:)

@Martin:async
/
await
在上面的问题中在哪里?@spender他使用“async”作为“asynchronous”的通用缩写,而不是C关键字。顺便说一句,而不是使用委托(操作)您可以使用ThreadPool.QueueUserWorkItem,或者更好地了解System.Threading.Tasks命名空间中的类型。这将是一项更好的时间投资。Rafael,我没有使用.NET 4.5,因为部署真正代码的服务器没有安装它。虽然如果你只是等待异步任务的结果,为什么要首先异步启动它……嗯,真的很明显!谢谢你。我在一个测试项目中这样做,所以在异步调用之后没有发生任何其他事情。忘记了线程将完全结束。谢谢。谢谢Servy,像spender一样,你回答了这个问题:)