2013-05-28 1 views
1

텍스트 파일의 멀티 스레드 펜스 라인을 입력 한 다음 요청 양식을 보내면 다른 텍스트 파일에 긍정적 인 응답을받은 후 해당 데이터를 게시합니다.텍스트를 모두 동기화하고 쓰는 방법은 무엇입니까?

public int index = -1; 
public int count = 1000; 

private static readonly object SyncIndex = new object(); 
private static readonly object SyncFiles = new object(); 

public void CreateThreads(int threads) 
{ 
    Thread[] threadArray; 
    for (int i = 0; i < (threadArray = new Thread[threads]).Length; i++) 
    { 
     threadArray[i] = new Thread(this.Run) { IsBackground = true }; 
     threadArray[i].Start(); 
    } 
} 


public void Run() 
{ 
    while (true) 
    { 
     lock(SyncIndex) { index++;} 
     //if (index > count) { break; } 
     string resp = Check(index.ToString()); 

     lock (SyncFiles) 
     { 
      if (resp == "true") 
      { 
       SaveText("good.txt", index.ToString()); 
      } 
      else 
      { 
       SaveText("bad.txt", index.ToString()); 
      } 
     } 

    } 
} 

public string Check(string login) 
{ 
    try 
    { 
     System.Net.WebRequest reqGET = System.Net.WebRequest.Create(@"http://www.minecraft.net/haspaid.jsp?user=" + login); 
     System.Net.WebResponse resp = reqGET.GetResponse(); 
     System.IO.Stream stream = resp.GetResponseStream(); 
     System.IO.StreamReader sr = new System.IO.StreamReader(stream); 
     string s = sr.ReadToEnd(); 

     if (s.Contains("true")) 
     { 
      return "true"; 
     } 
     else 
     { 
      return "false"; 
     } 
    } 
    catch 
    { 
     Check(login); 
    } 
    return ""; 
} 

//static ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(); 
private static void SaveText(string file, string text) 
{ 
    //cacheLock.EnterWriteLock(); 
    try 
    { 
     var write = new StreamWriter(file, true); 
     write.WriteLine(text); 
     write.Close(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
    //finally 
    //{ 
    // cacheLock.ExitWriteLock(); 
    //} 
} 

private void btStart_Click(object sender, EventArgs e) 
{ 
    CreateThreads(300); 
} 

무엇이 문제입니까? 카운트 = 1000 개 스레드 =

bad.txt 
299 
300 
301 
302 
303 
304 
305 
306 
307 
308 
310 
311 
312 
313 
314 
315 
316 

good.txt 
309 

(300)는 왜 텍스트 다음 300에서 시작? 어디서 잘못 됐습니까?

답변

1

먼저 작업 항목 당 하나의 스레드를 시작하지 않는 것이 좋습니다. 직접 스레드를 만드는 대신 Parallel.For을 사용하십시오.

버그 (인덱스를 직접 사용할 수 있음)를 방지 할뿐만 아니라로드 밸런싱을보다 효율적으로 수행 할 수 있습니다.

즉, 문제는 모든 스레드에서 동일한 변수를 사용하고 있다는 것입니다. 당신은 인덱스의 증가를 동기화하지만, 다른 스레드는 여전히 "변화"그 값은 당신이 그것을 사용하기 전에,

int localIndex; 
lock(SyncIndex) 
{ 
    index++; 
    localIndex = index; // Copy this here, before another thread can change it 
} 

// Use localIndex, not index, from here on... 

을 현재의 코드에서 : 당신은 임시 확인해야합니다.

+0

그리고 내 코드에 대해 더 자세히 설명 할 수 없습니까? 죄송합니다 나쁜 영어 – user2429282

+0

@ user2429282 그냥 내 코드를 바꿔, Run 메서드에서 "localIndex"로 "index"의 모든 인스턴스를 변경 ... 그 코드 작업을 maek 것입니다. StackOverflow는 "당신을 위해 코드를 작성"하는 것이 아닙니다 - 우리는 당신의 일을하는 것이 아니라 특정 질문에 대답하는 것을 돕기 위해 왔습니다.) –

+0

여러분, 도와 줘서 고마워요. – user2429282

관련 문제