好吧......我给了网站一个公平的搜索,并阅读了很多关于这个主题的帖子.我发现了这个问题:C#中一个简单线程池的代码特别有用.
但是,总是看起来,我需要的东西略有不同.
我查看了MSDN示例,并根据我的需要进行了调整.我引用的示例如下:http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80,printer).aspx
我的问题是这个.我有一组相当简单的代码,它通过HttpWebRequest
和WebResponse
类加载一个网页,并通过一个来读取结果Stream
.我在一个线程中触发此方法,因为它需要执行多次.该方法本身很短,但需要触发的次数(每次都有不同的数据)会有所不同.它可以是1到200之间的任何地方.
我读过的所有内容似乎都表明ThreadPool
班级是主要候选人.这就是事情变得棘手的事情.我可能需要发出100次这样的事情,但我最多只能运行3个线程(对于这个特定的任务).
我已经尝试设置MaxThreads
上ThreadPool
通过:
ThreadPool.SetMaxThreads(3, 3);
Run Code Online (Sandbox Code Playgroud)
我并不完全相信这种方法有效.此外,我不想破坏将在其上运行的系统上运行的其他网站或程序.因此,通过限制线程的#ThreadPool
,我可以确定这仅适用于我的代码和我的线程吗?
MSDN示例使用事件驱动方法和调用WaitHandle.WaitAll(doneEvents);
,这就是我这样做的方式.
所以我的问题的核心是,如何确保或指定可以为其代码运行的最大线程数,但让代码继续运行更多线程,因为之前的线程完成直到任意点?我是以正确的方式解决这个问题吗?
此致
贾森
好的,我添加了一个信号量方法并完全删除了ThreadPool
代码.看起来很简单.我从http://www.albahari.com/threading/part2.aspx获取了我的信息
这个例子向我展示了如何:
[此处的文字是网站的复制/粘贴]
Semaphore
容量为1的A 类似于a Mutex
或lock
,除了Semaphore
没有"所有者" - 它与线程无关.任何线程都可以调用Release
a Semaphore
,而使用Mutex
和lock
,只有获得资源的线程才能释放它.
在下面的示例中,十个线程执行一个循环,Sleep
中间有一个语句.A Semaphore
确保一次不超过三个线程可以执行该Sleep
语句:
class SemaphoreTest
{
static Semaphore s = new Semaphore(3, 3); // Available=3; Capacity=3 …
Run Code Online (Sandbox Code Playgroud) 我想弄清楚使用队列的最佳方法是什么.我有一个返回DataTable的进程.反过来,每个DataTable都与之前的DataTable合并.有一个问题,在最终的BulkCopy(OutOfMemory)之前要保留的记录太多.
所以,我已经确定我应该立即处理每个传入的DataTable.考虑一下ConcurrentQueue<T>
......但我不知道该WriteQueuedData()
方法如何知道将一个表出列并将其写入数据库.
例如:
public class TableTransporter
{
private ConcurrentQueue<DataTable> tableQueue = new ConcurrentQueue<DataTable>();
public TableTransporter()
{
tableQueue.OnItemQueued += new EventHandler(WriteQueuedData); // no events available
}
public void ExtractData()
{
DataTable table;
// perform data extraction
tableQueue.Enqueue(table);
}
private void WriteQueuedData(object sender, EventArgs e)
{
BulkCopy(e.Table);
}
}
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,除了我实际上没有订阅任何事件的事实,如果我ExtractData()
异步调用这将是我需要的全部内容吗?第二,我是否缺少关于ConcurrentQueue<T>
函数的方式以及需要某种形式的触发器与排队对象异步工作的东西?
更新
我刚刚派生出一个ConcurrentQueue<T>
具有OnItemQueued事件处理程序的类.然后:
new public void Enqueue (DataTable Table)
{
base.Enqueue(Table);
OnTableQueued(new TableQueuedEventArgs(Table));
}
public void OnTableQueued(TableQueuedEventArgs table)
{
EventHandler<TableQueuedEventArgs> handler = TableQueued; …
Run Code Online (Sandbox Code Playgroud)