2011-01-12 48 views
0

我有這個小的tcp/ip程序,對於我的生活我無法解決這個問題(我檢查谷歌)。當我在BeginReceive的回調委託中讀取一個緩衝區時,我將一些全局變量設置爲0,但是當函數啓動時,變量中有數據。我在班上兩個全局變量:TCP/IP,初始化異步調用的全局變量

string content; 
var buffer = ((byte[]) ar.AsyncState); 
int len = MySocket.EndReceive(ar); 
if (len > 0) 
{ 
    string cleanMessage; 
    content = Encoding.ASCII.GetString(buffer, 0, len); 
    if (MessageLength == 0) 
    { 
     MessageLength = GetMessageLength(content); 
     cleanMessage = StripNumber(content); 
    } 
    else 
     cleanMessage = content; 

    if(cleanMessage.Length <1) 
    { 
     if(MySocket.Connected) 
      MySocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, 
       new AsyncCallback(Read), buffer); 
     return; 
    } 
    if(MessageLength > cleanMessage.Length) 
    { 
     MessageLength = MessageLength - cleanMessage.Length; 
     amessage += cleanMessage; 
    } 
    else 
    { 
     amessage += cleanMessage.Substring(0, MessageLength); 
     if (OnRead != null) 
     { 
      var e = new CommandEventArgs(this, amessage); 
      Control target = null; 
      if (OnRead.Target is Control) 
       target = (Control)OnRead.Target; 
      if (target != null && target.InvokeRequired) 
       target.Invoke(OnRead, this, e); 
      else 
       OnRead(this, e); 
     } 

     string newMessage = cleanMessage.Substring(MessageLength); 
     MessageLength = GetMessageLength(newMessage); 
     amessage = StripNumber(newMessage); 
    } 
    MySocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, 
     new AsyncCallback(Read), buffer); 
    return; 
} 

在函數結束時,我有:

string newMessage = cleanMessage.Substring(MessageLength); 
MessageLength = GetMessageLength(newMessage); 
amessage = StripNumber(newMessage); 

GetMessageLength(newMessage)返回一個0和StripNumber(newMessage)返回一個空字符串,但下一次我打電話該函數在函數的開始處理之前,MessageLength = 30,並且amessage具有來自之前的數據。在程序中沒有其他地方可以引用這些變量,即我沒有訪問上面函數之外的變量,並且這兩個變量都是全局變量。

回答

1

我想象在這裏發生的事情是,你有同時處理數據併發呼叫,因此結果。

有兩種解決方案。第一種方法是在上面的代碼中放置觸及靜態(而非「全局」)變量的部分的鎖。第二種方法是封裝對靜態變量的訪問(你不能完全清楚哪些變量會被btw影響),並且在封裝中同步訪問(使用鎖定/監視器或其他機制)。

然後,在上面的代碼中使用局部變量,從本地複製靜態變量的值,執行您的工作,然後將它們分配回去。

如果您必須確保上面的代碼是連續運行的,換句話說,您必須確保讀取,修改和寫入都按順序進行,那麼您將使用第一種解決方案。

第二個將是當你有最後的勝利方法。

+0

是的,我是新來的線程:)讓我問你一個初學者問題,首先變量不是靜態的,它們只是在類中定義的,而不是在函數本地定義的。如果我想要順序訪問,並根據第一個建議進行操作,並且將變量鎖定在我想要更改的變量上,如果第一個線程更改值並退出鎖定,然後第二個線程在第一個線程完成發送該消息並將消息和MessageLength設置爲0.我嘗試了鎖定整個函數,但它沒有工作。謝謝您的幫助。 – Eitan 2011-01-12 15:17:33