繁体   English   中英

为什么不调用这个C#4.0异步方法?

[英]Why doesn't this C# 4.0 async method get called?

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

我创建了一个非常简单的测试应用程序,以确保我正在编码正确,但异步方法只是没有被调用。 任何人都能看到我做错了什么? 我顺便使用.NET 4.0,所以我不能使用await(这会更简单!)。

这是我的整个测试样本......

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");
    }
  }
}

谢谢你提供的所有帮助。

ThreadPool部署异步方法之前,您的程序正在终止。 保持你的程序开放一点。 也许在Main的末尾是Console.ReadKey()

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

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

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

你不是在等待完成,所以尝试这样的事情

 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通过调用实际执行

EndInvoke

AsyncState

像这样:

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

    Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
}

您需要做的另一个更改是,当您在main函数中实例化Action时,将操作本身作为BeginInvoke方法的'object'参数传递,如下所示:

Action d = new Action(DoStuff);
d.BeginInvoke(StuffDone, d);

这应该解决你的问题:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM