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)