【发布时间】:2013-01-23 16:22:39
【问题描述】:
初始情况
我正在开发一个 .NET Framework 4.0、C#、Winform 应用程序。应用程序将在 GridView 中列出(并测试)WebServiceOperations(当前有 60 个 DataRows => WebServiceOperations)。
目标
我必须通过单击按钮来测试/调用所有这些操作。每个操作都会创建一个类的新实例。在这个类中,我调用 WebServiceOperation async 并等待结果。然后对结果进行验证。整个代码使用委托和事件可以顺利运行。
现在是挑战/问题:单击该按钮时,我使用 for 循环 (int i = 0; i 换句话说,目前我正在“同时”触发 60 个操作 => 服务器同时处理 60 个请求时超载,我会超时。所以我需要以某种方式限制并发请求的数量,让我们同时说 10 个。 考虑一下,for 循环(我必须将请求排入队列)与我将请求出列的方法(process_result 事件)不在同一个线程中。我使用 ConcurrentQueue 进行了尝试,因为这种类型的集合似乎是线程安全的。
链接
示例代码真的很有帮助!
--- 这是我的解决方案/示例代码---
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Threading;
namespace ConcurrentQueueSample
{
class Program
{
static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(3);
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Interval = 1234;
timer.Enabled = true;
timer.Start();
for (int i = 0; i < 10; i++) new Thread(go).Start(i);
}
static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
semaphoreSlim.Release();
}
static void go(object i)
{
Console.WriteLine("id: {0}", i);
semaphoreSlim.Wait();
Console.WriteLine("id: {0} is in", i);
Thread.Sleep(1250);
Console.WriteLine("id: {0} left!", i);
}
}
}
【问题讨论】:
-
您可以在调用 Web 服务的类中使用 Semaphore 来限制并发请求的数量。
-
semaphoreSlim.Release()不应该在计时器中,它应该是在go中调用的最后一个东西。此外,您可能希望使用 ThreadPool 线程而不是完整线程。
标签: c# winforms stack queue concurrent-collections