대기열을 사용하는 가장 좋은 방법은 무엇인지 알아 내려고합니다. DataTable을 반환하는 프로세스가 있습니다. 각 DataTable은 이전 DataTable과 병합됩니다. 한 가지 문제가 있습니다. 마지막 BulkCopy (OutOfMemory)까지 보유 할 레코드가 너무 많습니다.ConcurrentQueue를 사용한 스레딩 방법 <T>
따라서 각 수신 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);
}
}
내 첫 번째 질문은 제쳐두고, 내가 ExtractData()
를 호출하면 실제로,에 가입 이벤트를 필요가 없다는 사실에서 비동기 적으로이 내가 필요로하는 모든 것입니까? 둘째로, 내가 대기하고있는 객체와 비동기 적으로 작동하기 위해 어떤 형태의 트리거가 필요하고 기능이 필요합니까?
업데이트 나는 그냥 OnItemQueued 이벤트 핸들러가 ConcurrentQueue<T>
에서 클래스를 파생했다. 그 다음 :
new public void Enqueue (DataTable Table)
{
base.Enqueue(Table);
OnTableQueued(new TableQueuedEventArgs(Table));
}
public void OnTableQueued(TableQueuedEventArgs table)
{
EventHandler<TableQueuedEventArgs> handler = TableQueued;
if (handler != null)
{
handler(this, table);
}
}
이 구현에 대한 우려 사항은 무엇입니까?
2 개의 스레드가 있다고 생각했습니다. 주 스레드는 기본적으로 이벤트가 트리거 될 때까지 대기합니다. 두 번째 스레드는'ExtractData()'에 대한 비동기 호출로 시작합니다. 비동기 콜백에서 추출 프로세스를 계속 진행합니다. – IAbstract
사실, 나는 그것을 거꾸로 가지고 있다고 생각한다; 주 스레드는 대기열에 들어가는 데이터 테이블이어야합니다. 대기열에있는 항목 이벤트 트리거를 통해 비동기 쓰기 메소드를 시작하십시오. – IAbstract