为什么callback / endinvoke在调用所有start调用之后发生?

时间:2014-02-27 16:26:12

标签: c# .net multithreading compiler-construction

我要做的是排队列出类似的任务。每项任务完成所需的时间很短,但其中有很多。对于列表中的每个项目,我创建一个委托并调用delegate.BeginInvoke方法然后我移动到创建下一个。

我希望在下面的例子中我至少会得到一个“ * ** * ** 结束调用 * *** “发生 BEFORE 调用所有开始调用。相反,看起来编译器在收到任何结束调用之前启动了所有的开始调用。

这是正常行为吗?还有另一种方法可以在另一个线程上发送任务/方法并在继续激活更多任务的同时接收它吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace AsyncResultTesting
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine("Starting");
            for (int i = 0; i < 100; i++)
            {
                delMeth d = new delMeth(sleepMethod);
                Console.WriteLine(string.Format("Calling the begin invoke from thread: {0} for ID: {1}", Thread.CurrentThread.ManagedThreadId.ToString(), i.ToString()));
                IAsyncResult ar = d.BeginInvoke(i, callbackMessage, d);
            }
            Console.ReadLine();
        }

        private delegate int delMeth(int id);

        private static int sleepMethod(int id)
        {
            Console.WriteLine(Environment.NewLine + String.Format("Thread: {0} is sleeping. Delegate id is {1}", Thread.CurrentThread.ManagedThreadId.ToString(),id.ToString()));
            Console.WriteLine(String.Format("Thread Properties IsThreadPoolThread? = {0} isThreadBackground? = {1} ThreadState: = {2}", Thread.CurrentThread.IsThreadPoolThread.ToString(), Thread.CurrentThread.IsBackground.ToString(), Thread.CurrentThread.ThreadState.ToString()));
            Console.WriteLine("");
            Thread.Sleep(100);              
            return id;

        }

        private static void callbackMessage(IAsyncResult ar)
        {
            delMeth d = (delMeth)ar.AsyncState;
            int result = d.EndInvoke(ar);
            Console.WriteLine(Environment.NewLine + "************************ END INVOKE *****************************");
            Console.WriteLine(String.Format("Delegate was just called back for id: {0}", result.ToString()));
        }

    }


}

不幸的是我必须使用.NET 3.5进行设计,因此我无法使用任务异步处理。

1 个答案:

答案 0 :(得分:1)

USR是正确的。一切都在运作我的期望。如果我睡了10毫秒,那么我看到EndInvokes回到了BeginInvokes的中间。

感谢USR。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace AsyncResultTesting
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine("Starting");



            for (int i = 0; i < 150; i++)            {
                delMeth d = new delMeth(sleepMethod);
                Console.WriteLine(string.Format("Calling the begin invoke from thread: {0} for ID: {1}", Thread.CurrentThread.ManagedThreadId.ToString(), i.ToString()));
                IAsyncResult ar = d.BeginInvoke(i, new AsyncCallback(callbackMessage), d);
            }
            Console.ReadLine();
        }

        private delegate int delMeth(int id);

        private static int sleepMethod(int id)
        {
            Console.WriteLine(Environment.NewLine + String.Format("Thread: {0} is sleeping. Delegate id is {1}", Thread.CurrentThread.ManagedThreadId.ToString(),id.ToString()));
            Console.WriteLine(String.Format("Thread Properties IsThreadPoolThread? = {0} isThreadBackground? = {1} ThreadState: = {2}", Thread.CurrentThread.IsThreadPoolThread.ToString(), Thread.CurrentThread.IsBackground.ToString(), Thread.CurrentThread.ThreadState.ToString()));
            Console.WriteLine("");
            Thread.Sleep(10);              
            return id;

        }

        private static void callbackMessage(IAsyncResult ar)
        {
            delMeth d = (delMeth)ar.AsyncState;
            int result = d.EndInvoke(ar);
            Console.WriteLine(Environment.NewLine + "************************ END INVOKE *****************************");
            Console.WriteLine(String.Format("Delegate was just called back for id: {0}", result.ToString()));
        }

    }


}