我試圖創建一個windows服務,當文件到達FTP位置時,通過TCP向相關用戶發送消息。我已經設置了所有的文件檢測部分,但我需要一些消息傳遞方面的幫助。在1個線程中讀取列表,在另一箇中寫入
由於會有多個用戶同時訂閱此服務,因此需要能夠處理多個連接,因此我在服務啓動時創建TCPServer服務器,並開始監聽傳入連接。當到達時,代碼將連接添加到連接列表。
到目前爲止,這麼好。
傳入文件觸發向相關客戶端發送消息時出現問題。嘗試訪問連接列表失敗,因爲我必須從一個單獨的線程中執行它(因爲偵聽新連接的線程在此期間無法執行其他任何操作)。
在調試模式下運行,我發現新連接可以正確地增加ClientList的計數,但是當調試器返回到發送消息的類時,ClientList變量會重置爲0,就像我已經創建該類的新實例。任何想法將不勝感激。
我的代碼如下:
namespace WindowsService1
{
class MSGServer
{
TcpListener server = null;
Int32 port = 13000;
IPAddress localAddr;
List<ClientConn> ClientList = new List<ClientConn>();
Byte[] data;
private object l_lock = new object();
public void CreateServer()
{
localAddr = IPAddress.Parse("172.26.114.71");
server = new TcpListener(localAddr, port);
server.Start();
NewConnection();
}
public void NewConnection()
{
Debugger.Break();
while (true)
{
ClientConn Client = new ClientConn();
Client.TClient = server.AcceptTcpClient();
NetworkStream stream = Client.TClient.GetStream();
data = new Byte[256];
String MSG = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length);
Client.ClientUserName = Encoding.ASCII.GetString(data, 0, bytes);
stream.Write(data, 0, bytes);
lock (ClientList)
{
ClientList.Add(Client);
}
}
}
public Boolean SendNotification(string UserName, string FFolder, string FName)
{
Debugger.Break();
NetworkStream Stream;
bool MsgSent = false;
foreach (ClientConn Client in ClientList)
{
if (Client.ClientUserName == UserName)
{
Byte[] MsgByte = Encoding.ASCII.GetBytes(FFolder + "|" + FName);
Stream = Client.TClient.GetStream();
Stream.Write(MsgByte, 0, MsgByte.Length);
MsgSent = true;
}
}
return MsgSent;
}
public void CLoseAllConnections()
{
foreach (ClientConn ConnToClose in ClientList)
{
ConnToClose.TClient.Close();
}
}
}
class ClientConn
{
private string CUser;
TcpClient Client;
public string ClientUserName
{
get { return CUser;}
set { CUser = value; }
}
public TcpClient TClient
{
get { return Client; }
set { Client = value; }
}
}
}
更新:通過傳遞運行CreateServer()的線程最終調用sendNotification的方法的類的實例解決了我說的是下面的問題。感謝您的全力幫助
'List'不是爲了同時修改和訪問不同的線程而設計的。您應該使用專門爲此設計的集合類型。 'BlockingCollection'應該可以滿足您的需求。 – Servy