xml 파일을 연결된 목록 대기열에서 처리 할 Windows 서비스가 있습니다. 큐에있는 파일은 파일을 만들 때 FileSystemWatcher 이벤트에 의해 추가되었습니다.ProcessingQueue.Count가 다중 스레딩 응용 프로그램에서 올바른지 확인하십시오.
namespace XMLFTP
{
public class XML_Processor : ServiceBase
{
public string s_folder { get; set; }
public XML_Processor(string folder)
{
s_folder = folder;
}
Thread worker;
FileSystemWatcher watcher;
DirectoryInfo my_Folder;
public static AutoResetEvent ResetEvent { get; set; }
bool running;
public bool Start()
{
my_Folder = new DirectoryInfo(s_folder);
bool success = true;
running = true;
worker = new Thread(new ThreadStart(ServiceLoop));
worker.Start();
// add files to queue by FileSystemWatcher event
return (success);
}
public bool Stop()
{
try
{
running = false;
watcher.EnableRaisingEvents = false;
worker.Join(ServiceSettings.ThreadJoinTimeOut);
}
catch (Exception ex)
{
return (false);
}
return (true);
}
public void ServiceLoop()
{
string fileName;
while (running)
{
Thread.Sleep(2000);
if (ProcessingQueue.Count > 0)
{
// process file and write info to DB.
}
}
}
void watcher_Created(object sender, FileSystemEventArgs e)
{
switch (e.ChangeType)
{
case WatcherChangeTypes.Created:// add files to queue
}
}
}
}
스레드 안전 문제 일 수 있습니다. ProcessingQueue.Count의 액세스가 로크에 의해 보호되지 않기 때문에 다른 스레드는 "큐"을 바꾸는 경우
while (running)
{
Thread.Sleep(2000);
if (ProcessingQueue.Count > 0)
{
// process file and write info to DB.
}
}
의 개수는 변화 할 수있다. 결과적으로 프로세스 파일 부분이 실패 할 수 있습니다. 잠금이 조기에 해제로
public static int Count
{
get { lock (syncRoot) return _files.Count; }
}
: 당신이뿐만 Count 속성을 구현하는 경우 그 또한 사건.
내 두 가지 질문 :
- 어떻게 ProcessingQueue.Count이 올 수 있도록? 내가 .NET 프레임 워크 4.5 BlockingCollection 기술을 사용하는 경우
는, 샘플 코드 등 :
class ConsumingEnumerableDemo { // Demonstrates: // BlockingCollection<T>.Add() // BlockingCollection<T>.CompleteAdding() // BlockingCollection<T>.GetConsumingEnumerable() public static void BC_GetConsumingEnumerable() { using (BlockingCollection<int> bc = new BlockingCollection<int>()) { // Kick off a producer task Task.Factory.StartNew(() => { for (int i = 0; i < 10; i++) { bc.Add(i); Thread.Sleep(100); // sleep 100 ms between adds } // Need to do this to keep foreach below from hanging bc.CompleteAdding(); }); // Now consume the blocking collection with foreach. // Use bc.GetConsumingEnumerable() instead of just bc because the // former will block waiting for completion and the latter will // simply take a snapshot of the current state of the underlying collection. foreach (var item in bc.GetConsumingEnumerable()) { Console.WriteLine(item); } } } }
샘플에 대기열에 내 동적 계수를 적용하는 방법, 반복 절 등의 일정 (10)를 사용 그것?
멋진데! 코드에서 IsCompleted는 어디에 있습니까? –
@Love :'GetConsumingEnumerable'은'IsCompleted'를 검사합니다. 이것은'BlockingCollection' 클래스의 속성입니다. –