Multithreading ThreadPool.QueueUserWorkItem和异步编程

Multithreading ThreadPool.QueueUserWorkItem和异步编程,multithreading,Multithreading,我在下面编写了一个示例程序 class Program { static int x = 2; static void Main(string[] args) { Console.WriteLine("Thread ID {0} and Main Called!", Thread.CurrentThread.ManagedThreadId); ThreadPool.QueueUserWor

我在下面编写了一个示例程序

class Program
    {
        static int x = 2;

        static void Main(string[] args)
        {
            Console.WriteLine("Thread ID {0} and Main Called!", Thread.CurrentThread.ManagedThreadId);

            ThreadPool.QueueUserWorkItem(Count, args);
            ThreadPool.QueueUserWorkItem(Count2, args);

            Console.WriteLine("Thread ID {0} and Main Done!", Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }
        static void Count(object args)
        { 
            for (int i = 0; i < 10; i++)
            {
                x = x + 2;
                Console.WriteLine("Thread ID {0} AND Count 1: " + x, Thread.CurrentThread.ManagedThreadId);
            }
        }
        static void Count2(object args)
        {
            for (int i = 0; i < 10; i++)
            {
                x = x + 2;
                Console.WriteLine("Thread ID {0} AND Count 2: " + x, Thread.CurrentThread.ManagedThreadId);
            }
        }
    }
类程序
{
静态int x=2;
静态void Main(字符串[]参数)
{
WriteLine(“线程ID{0}和Main已调用!”,Thread.CurrentThread.ManagedThreadId);
ThreadPool.QueueUserWorkItem(计数,参数);
ThreadPool.QueueUserWorkItem(Count2,args);
WriteLine(“线程ID{0}和Main Done!”,Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
静态无效计数(对象参数)
{ 
对于(int i=0;i<10;i++)
{
x=x+2;
WriteLine(“线程ID{0}和计数1:+x,Thread.CurrentThread.ManagedThreadId”);
}
}
静态无效计数2(对象参数)
{
对于(int i=0;i<10;i++)
{
x=x+2;
WriteLine(“线程ID{0}和计数2:+x,Thread.CurrentThread.ManagedThreadId”);
}
}
}
当使用ThreadPool.QueueUserWorkItem调用Count方法时,我注意到Main在Count方法完成之前就完成了,Count2方法与Count方法纠缠在一起

Main(和Count2)是否需要等待Count方法完成?我不想使用锁或Thread.Sleep(因为我不知道计数操作需要多长时间)。我曾读到过在这种情况下使用异步调用或等待的地方

有什么想法吗?

我想这就是你想要的

**编辑:** 这是修改后的代码(未测试)。在本例中,我使用AutoResetEvent而不是手动

class Program
{
    static int x = 2;
    // Define an array with two AutoResetEvent WaitHandles.
    static WaitHandle[] waitHandles = new WaitHandle[] 
    {
        new AutoResetEvent(false),
        new AutoResetEvent(false)
    };



    static void Main(string[] args)
    {
        Console.WriteLine("Thread ID {0} and Main Called!", Thread.CurrentThread.ManagedThreadId);

        ThreadPool.QueueUserWorkItem(new WaitCallback(Count), waitHandles[0]);
        ThreadPool.QueueUserWorkItem(new WaitCallback(Count2), waitHandles[1]);
        WaitHandle.WaitAll(waitHandles);


        Console.WriteLine("Thread ID {0} and Main Done!", Thread.CurrentThread.ManagedThreadId);
        Console.ReadLine();
    }
    static void Count(object args)
    {
        AutoResetEvent are = (AutoResetEvent)args;

        for (int i = 0; i < 10; i++)
        {
            x = x + 2;
            Console.WriteLine("Thread ID {0} AND Count 1: " + x, Thread.CurrentThread.ManagedThreadId);
        }
        are.Set();

    }
    static void Count2(object args)
    {
        AutoResetEvent are = (AutoResetEvent)args;

        for (int i = 0; i < 10; i++)
        {
            x = x + 2;
            Console.WriteLine("Thread ID {0} AND Count 2: " + x, Thread.CurrentThread.ManagedThreadId);
        }
        are.Set();
    }
}
类程序
{
静态int x=2;
//定义一个具有两个AutoResetEvent WaitHandles的数组。
静态WaitHandle[]waitHandles=新的WaitHandle[]
{
新自动重置事件(错误),
新自动重置事件(错误)
};
静态void Main(字符串[]参数)
{
WriteLine(“线程ID{0}和Main已调用!”,Thread.CurrentThread.ManagedThreadId);
QueueUserWorkItem(新的WaitCallback(计数),waitHandles[0]);
QueueUserWorkItem(新的WaitCallback(Count2),waitHandles[1]);
WaitHandle.WaitAll(waitHandles);
WriteLine(“线程ID{0}和Main Done!”,Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
静态无效计数(对象参数)
{
AutoResetEvent是=(AutoResetEvent)参数;
对于(int i=0;i<10;i++)
{
x=x+2;
WriteLine(“线程ID{0}和计数1:+x,Thread.CurrentThread.ManagedThreadId”);
}
are.Set();
}
静态无效计数2(对象参数)
{
AutoResetEvent是=(AutoResetEvent)参数;
对于(int i=0;i<10;i++)
{
x=x+2;
WriteLine(“线程ID{0}和计数2:+x,Thread.CurrentThread.ManagedThreadId”);
}
are.Set();
}
}
我想这就是你想要的

**编辑:** 这是修改后的代码(未测试)。在本例中,我使用AutoResetEvent而不是手动

class Program
{
    static int x = 2;
    // Define an array with two AutoResetEvent WaitHandles.
    static WaitHandle[] waitHandles = new WaitHandle[] 
    {
        new AutoResetEvent(false),
        new AutoResetEvent(false)
    };



    static void Main(string[] args)
    {
        Console.WriteLine("Thread ID {0} and Main Called!", Thread.CurrentThread.ManagedThreadId);

        ThreadPool.QueueUserWorkItem(new WaitCallback(Count), waitHandles[0]);
        ThreadPool.QueueUserWorkItem(new WaitCallback(Count2), waitHandles[1]);
        WaitHandle.WaitAll(waitHandles);


        Console.WriteLine("Thread ID {0} and Main Done!", Thread.CurrentThread.ManagedThreadId);
        Console.ReadLine();
    }
    static void Count(object args)
    {
        AutoResetEvent are = (AutoResetEvent)args;

        for (int i = 0; i < 10; i++)
        {
            x = x + 2;
            Console.WriteLine("Thread ID {0} AND Count 1: " + x, Thread.CurrentThread.ManagedThreadId);
        }
        are.Set();

    }
    static void Count2(object args)
    {
        AutoResetEvent are = (AutoResetEvent)args;

        for (int i = 0; i < 10; i++)
        {
            x = x + 2;
            Console.WriteLine("Thread ID {0} AND Count 2: " + x, Thread.CurrentThread.ManagedThreadId);
        }
        are.Set();
    }
}
类程序
{
静态int x=2;
//定义一个具有两个AutoResetEvent WaitHandles的数组。
静态WaitHandle[]waitHandles=新的WaitHandle[]
{
新自动重置事件(错误),
新自动重置事件(错误)
};
静态void Main(字符串[]参数)
{
WriteLine(“线程ID{0}和Main已调用!”,Thread.CurrentThread.ManagedThreadId);
QueueUserWorkItem(新的WaitCallback(计数),waitHandles[0]);
QueueUserWorkItem(新的WaitCallback(Count2),waitHandles[1]);
WaitHandle.WaitAll(waitHandles);
WriteLine(“线程ID{0}和Main Done!”,Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
静态无效计数(对象参数)
{
AutoResetEvent是=(AutoResetEvent)参数;
对于(int i=0;i<10;i++)
{
x=x+2;
WriteLine(“线程ID{0}和计数1:+x,Thread.CurrentThread.ManagedThreadId”);
}
are.Set();
}
静态无效计数2(对象参数)
{
AutoResetEvent是=(AutoResetEvent)参数;
对于(int i=0;i<10;i++)
{
x=x+2;
WriteLine(“线程ID{0}和计数2:+x,Thread.CurrentThread.ManagedThreadId”);
}
are.Set();
}
}

我将介绍两种模式。这两种模式都具有高度可扩展性,因为它们可以同时处理数百甚至数千个工作项。你必须严格遵循这些模式。任何偏差都可能导致事件的信号和等待之间的竞争状态。我已经在循环的上下文中介绍了这些模式来概括它,但是在您的例子中,您将使用对
ThreadPool.QueueUserWorkItem
的两个单独调用来替换该循环

第一种模式需要.NET4.0中提供的类或作为下载的一部分提供的类

var finished = new CountdownEvent(1);
for (int i = 0; i < NUM_WORK_ITEMS; i++)
{
  finished.AddCount();
  ThreadPool.QueueUserWorkItem(
    (state) =>
    {
      try
      {
        // Your work item code goes here.
        // Call Count, Count2, or whatever.
      }
      finally
      {
        finished.Signal();
      }
    });
}
finished.Signal();
finished.WaitOne();
var finished=新的倒计时事件(1);
对于(int i=0;i
{
尝试
{
//您的工作项代码在这里。
//呼叫Count,Count2,或者其他什么。
}
最后
{
完成。信号();
}
});
}
完成。信号();
完成。WaitOne();
以下模式适用于任何版本的.NET Framework1。但它没有那么优雅

int count = 1;
var finished = new ManualResetEvent(false);
for (int i = 0; i < NUM_WORK_ITEMS; i++)
{
  Interlocked.Increment(ref count);
  ThreadPool.QueueUserWorkItem(
    (state) =>
    {
      try
      {
        // Your work item code goes here.
        // Call Count, Count2, or whatever.
      }
      finally
      {
        if (Interlocked.Decrement(ref count) == 0) finished.Set();
      }
    });
}
if (Interlocked.Decrement(ref count) == 0) finished.Set();
finished.WaitOne();
int count=1;
var finished=新的手动重置事件(false);
对于(int i=0;i
{
尝试
{
//您的工作项代码在这里。
//呼叫Count,Count2,或者其他什么。
}
最后
{
if(Interloc)