"개체 풀"을 개발했으며 Thread.Sleep()을 사용하지 않고는 "나쁜 연습"이라고 생각하지 않습니다.Thread.Sleep없는 공유 객체 풀?
내 다른 질문 "Is there a standard way of implementing a proprietary connection pool in .net?"과 관련이 있습니다. 개체 풀의 배경은 데이터베이스 연결에 사용되는 연결 풀 뒤에있는 아이디어와 비슷합니다. 그러나, 제 경우에는 그것을 표준 ASP.NET 웹 서비스 (IIS6에서 실행)에서 제한된 리소스를 공유하는 데 사용하고 있습니다. 즉, 많은 스레드가이 제한된 리소스에 대한 액세스를 요청할 것입니다. 풀은 이러한 객체를 추출하고 ("Get"), 일단 사용 가능한 풀 객체가 모두 사용되면 다음 요청 스레드는이 객체 중 하나가 다시 사용 가능하게 될 때까지 기다립니다 . 개체가이 설정 한 시간에 사용할 수있게하지 않는 경우, 한 번) 대상으로 수행 "넣어", 타임 아웃 오류가 발생합니다 여기
는 코드입니다.public class SimpleObjectPool
{
private const int cMaxGetTimeToWaitInMs = 60000;
private const int cMaxGetSleepWaitInMs = 10;
private object fSyncRoot = new object();
private Queue<object> fQueue = new Queue<object>();
private SimpleObjectPool()
{
}
private static readonly SimpleObjectPool instance = new SimpleObjectPool();
public static SimpleObjectPool Instance
{
get
{
return instance;
}
}
public object Get()
{
object aObject = null;
for (int i = 0; i < (cMaxGetTimeToWaitInMs/cMaxGetSleepWaitInMs); i++)
{
lock (fSyncRoot)
{
if (fQueue.Count > 0)
{
aObject = fQueue.Dequeue();
break;
}
}
System.Threading.Thread.Sleep(cMaxGetSleepWaitInMs);
}
if (aObject == null)
throw new Exception("Timout on waiting for object from pool");
return aObject;
}
public void Put(object aObject)
{
lock (fSyncRoot)
{
fQueue.Enqueue(aObject);
}
}
}
사용을 사용하려면, 다음 중 하나를 수행 할 수 있습니다.
public void ExampleUse()
{
PoolObject lTestObject = (PoolObject)SimpleObjectPool.Instance.Get();
try
{
// Do something...
}
finally
{
SimpleObjectPool.Instance.Put(lTestObject);
}
}
지금 제가 갖고있는 질문은 입니다 : 어떻게 이것을 쓰면 Thread.Sleep()을 없앨 수 있습니까?
(내가 왜 이것을하고 싶은지는 테스트에서 "거짓"시간 초과가 발생했다고 생각하기 때문입니다. 내 테스트 응용 프로그램에는 3 개의 객체가있는 객체 풀이 있습니다 .12 개의 스레드가 회전합니다. 각 스레드는 풀에서 객체를 100 번 가져옵니다. 스레드가 객체를 풀에서 가져 오면 2,000ms 동안 유지하고, 그렇지 않으면 다음 반복으로 넘어갑니다. 어느 시점에서든 객체를 기다리는 중일 때 .9 x 2000 ms는 18,000 ms이며, thread가 객체를 기다려야하는 최대 시간이다. get timeout은 60,000 ms로 설정되어있어, thread가 타임 아웃 할 필요는 없다. 뭔가 잘못 됐어. 그리고 나는 그 스레드를 의심해. 잠깐.
단일 공유 자원의 여러 독자가 세마포어처럼 들립니다. 왜 그걸 사용하지 않니? – Amirshk
다른 사람들이해야 할 일에 답했습니다. 여기서 Sleep()이 나쁜 생각 인 이유에 대해서만 언급 할 것입니다. 스레드가 깨어있을 때 풀에 객체가있을 것이라는 것을 보장하는 것은 아무것도 없습니다. 따라서 약간의 "행운"을 가진 스레드는 다른 스레드가 풀링 된 객체를 선택하는 동안 잠자고있게 할 수 있습니다. 필요한 것은 객체가 사용 가능하게 될 때 스레드를 깨울 대기 메커니즘입니다. –