Invalid thread operation, Invoke method does not work - c#

I have an online chat code, there is a list of logged in users on the system. There is a problem adding the users name in the listBox; The error is as follows: Invalid thread operation: control 'lbClients' accessed from a thread that is not the one in which it was created.
I tried the Invoke method, but it also did not work. With the Invoke method, the server adds the user to the list, but when the user disconnects, the list of users logged on to the server does not refresh. What can be done?
public void ServiceClient()
{
Socket client = clientsocket;
bool keepalive = true;
while (keepalive)
{
Byte[] buffer = new Byte[1024];
client.Receive(buffer);
string clientcommand = System.Text.Encoding.ASCII.GetString(buffer);
string[] tokens = clientcommand.Split(new Char[]{'|'});
Console.WriteLine(clientcommand);
if (tokens[0] == "CONN")
{
for(int n=0; n<clients.Count; n++) {
Client cl = (Client)clients[n];
SendToClient(cl, "JOIN|" + tokens[1]);
}
EndPoint ep = client.RemoteEndPoint;
//string add = ep.ToString();
Client c = new Client(tokens[1], ep, clientservice, client);
this.Invoke(new Action(() => clients.Add(c)));
string message = "LIST|" + GetChatterList() +"\r\n";
SendToClient(c, message);
try
{
lbClients.Items.Add(c);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
else if (tokens[0] == "CHAT")
{
for(int n=0; n<clients.Count; n++)
{
Client cl = (Client)clients[n];
SendToClient(cl, clientcommand);
}
}
else if (tokens[0] == "PRIV")
{
string destclient = tokens[3];
for(int n=0; n<clients.Count; n++) {
Client cl = (Client)clients[n];
if(cl.Name.CompareTo(tokens[3]) == 0)
SendToClient(cl, clientcommand);
if(cl.Name.CompareTo(tokens[1]) == 0)
SendToClient(cl, clientcommand);
}
}
else if (tokens[0] == "GONE")
{
int remove = 0;
bool found = false;
int c = clients.Count;
for(int n=0; n<c; n++)
{
Client cl = (Client)clients[n];
SendToClient(cl, clientcommand);
if(cl.Name.CompareTo(tokens[1]) == 0)
{
remove = n;
found = true;
lbClients.Items.Remove(cl);
//lbClients.Items.Remove(cl.Name + " : " + cl.Host.ToString());
}
}
if(found)
this.Invoke(new Action(() => clients.RemoveAt(remove)));
client.Close();
keepalive = false;
}
else
{
int remove = 0;
bool found = false;
int c = clients.Count;
for (int n = 0; n < c; n++)
{
Client cl = (Client)clients[n];
//SendToClient(cl, clientcommand);
if (cl.Name.CompareTo(tokens[1]) == 0)
{
remove = n;
found = true;
lbClients.Items.Remove(cl);
//lbClients.Items.Remove(cl.Name + " : " + cl.Host.ToString());
}
}
if (found)
clients.RemoveAt(remove);
client.Close();
keepalive = false;
}
}
}

Related

Parallel compression folder, best solution in c#

I need to compress more folder at same time in different archivie to goes more quikly.
I tried to use a main backgroundworker and from this I did a for cycle to start other backgroundworker for each folder. I notice that the backgroundworker starts all at same time but not works together what is the best way to do a parallel archive?what you suggest?
to create the archive I use the zipforge library
DoWork of the main backgroundworker
if (Directory.Exists(destination))
{
if (MessageBox.Show("", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
{
goto EXIT_UTENTE;
}
else
{
bool finish = false;
int j = 1;
string dest_appoggio = destination;
do
{
dest_appoggio = destination + "_" + j;
if (Directory.Exists(dest_appoggio))
{
j++;
}
else
{
destination = dest_appoggio;
dataprogressiva = data + "_" + j;
finish = true;
}
}
while (finish == false);
}
}
destinationdefault = destination;
var row_list1 = GetDataGridRows(dgwRobot);
int riga = -1;
foreach (DataGridRow single_row1 in row_list1)
{
bool rowselected = false;
single_row1.Dispatcher.Invoke(new Action(() => { rowselected = single_row1.IsSelected; }));
if (rowselected == true)
{
riga = single_row1.GetIndex();
var robotProcessed = false;
while (!robotProcessed)
{
for (var threadNum = 0; threadNum < MaxBackupContemporanei; threadNum++)
{
if (!threadArray[threadNum].IsBusy)
{
threadArray[threadNum].RunWorkerAsync(riga);
robotProcessed = true;
break;
}
}
}
}
Thread.Sleep(500);
}
bool bwTerminati = false;
while (!bwTerminati)
{
for (var threadNum = 0; threadNum < MaxBackupContemporanei; threadNum++)
{
if (threadArray[threadNum].IsBusy)
{
bwTerminati = false;
threadNum = MaxBackupContemporanei;
}
else
{
bwTerminati = true;
}
}
}

UI not updating from asynchronous event

i use the Asynchronous socket Client event to receive message from server.
i receive message from client DataIn(my Event Name) and add to list box ,but not happen to show on UI!
protected void WebSocketClientControl1_OnChatNotification(List < SocketUi > sender) {
ClientScript.RegisterStartupScript(GetType(), "hwa", "javascript:__doPostBack('WebSocketClientControl1','')", true);
}
i cant use the (Response.Redirect & Server.Transfer).
this 2 function have error run time.
i call the javaScript function to show message , not happen on screen.
its my Socket code
public delegate void OnChatNotification(List<SocketUi> sender);
public class WebSocketClientControl : System.Web.UI.Control, IPostBackDataHandler
{
public static ClientService _internalClientService = new ClientService(DServerConfig.ServerAddress.ToString(),
DServerConfig.ServerSoketPort);
public event OnChatNotification OnChatNotification = delegate { };
public WebSocketClientControl()
{
_internalClientService.OnChat += _internalClientService_OnChat;
}
public void Connect(long userID, SocketEnums.EntityType usertype, string username, string key)
{
_internalClientService.Connect(userID, usertype, username, key);
}
private void _internalClientService_OnChat(List<SocketUI.SocketUi> sender)
{
if (OnChatNotification != null)
OnChatNotification(sender);
}
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
String presentValue = postDataKey;
String postedValue = postCollection[postDataKey];
if (presentValue == null || !presentValue.Equals(postedValue))
{
return true;
}
return false;
}
public void RaisePostDataChangedEvent()
{
}
}
its my ui Code
private void WebSocketClientControl1_OnChatNotification(List<SocketUI.SocketUi> sender)
{
foreach (SocketUi socketUi in sender)
{
switch (socketUi.DSocketType)
{
case SocketEnums.DSocketType.Chat:
foreach (SocketUI.tb_Chat chatUi in socketUi.Chats)
{
for (int i = 0; i < ASPxPageControl1.TabPages.Count; i++)
{
if (ASPxPageControl1.TabPages[i].Name == "uxTabPage_" + _channels[i].ID.ToString())
{
switch (chatUi.ChatMessegeType)
{
case (int)Enums.ChatMessegeType.Message:
SetNewMessageOnUi(HelperD.UiChat_To_Tb_Chat(chatUi));
break;
case (int)Enums.ChatMessegeType.Readed:
break;
case (int)Enums.ChatMessegeType.OnLinedUser:
break;
case (int)Enums.ChatMessegeType.OffLinedUser:
break;
case (int)Enums.ChatMessegeType.JoinChannle:
case (int)Enums.ChatMessegeType.LeftChannle:
GetUserChannel(chatUi.ChannelID.ID);
break;
case (int)Enums.ChatMessegeType.TypingUser:
for (int j = 0; j < ASPxPageControl1.TabPages[i].Controls.Count; j++)
{
if (ASPxPageControl1.TabPages[i].Controls[j] is System.Web.UI.WebControls.Label &&
ASPxPageControl1.TabPages[i].Controls[j].ID ==
"uxLabel_Status" + ASPxPageControl1.TabPages[i].DataItem.ToString())
{
System.Web.UI.WebControls.Label uxLabel_StatusTemp = new System.Web.UI.WebControls.Label();
uxLabel_StatusTemp = (System.Web.UI.WebControls.Label)ASPxPageControl1.TabPages[i].Controls[j];
uxLabel_StatusTemp.Text = " درحال تایپ " + socketUi.UserName + "...";
// timer1.Start();
}
}
break;
}//End For
// listBox_Message.Items.Add("Me:=>" + chatUi.Message + "\n\r");
}
}
}//End For
break;
}
}
}
private void SetNewMessageOnUi(UiSideLanguage.Database.Chat.tb_Chat item)
{
ASPxTextBox_Message.Text = "";
for (int i = 0; i < ASPxPageControl1.TabPages.Count; i++)
{
for (int j = 0; j < ASPxPageControl1.TabPages[i].Controls.Count; j++)
{
if (ASPxPageControl1.TabPages[i].Controls[j] is System.Web.UI.WebControls.ListBox && ASPxPageControl1.TabPages[i].Controls[j].ID == "uxListView_Chat" + ASPxPageControl1.TabPages[i].DataItem.ToString())
{
System.Web.UI.WebControls.ListBox userListView = (System.Web.UI.WebControls.ListBox)ASPxPageControl1.TabPages[i].Controls[j];
System.Web.UI.WebControls.ListItem listViewItemTemp = new System.Web.UI.WebControls.ListItem();
if (item.AddUser.ID == Language.CacheEntity.CurrentUser.ID)
{
listViewItemTemp.Text = " :من " + item.Message;
// listViewItemTemp.ForeColor = Color.DarkCyan;
}
else
{
listViewItemTemp.Text = item.AddUser.UserName + " : " + item.Message;
// listViewItemTemp.ForeColor = Color.DarkRed;
}
listViewItemTemp.Value = item.MessageFlagID.ToString();
System.Web.UI.WebControls.ListItem isHaveChatItem = null;
foreach (System.Web.UI.WebControls.ListItem chatitemListView in userListView.Items)
{
if (Language.HelperD.GetLong(chatitemListView.Value) == item.MessageFlagID)
{
isHaveChatItem = chatitemListView;
break;
}
}
if (isHaveChatItem != null)
{
if (item.AddUser.ID == Language.CacheEntity.CurrentUser.ID)
{
isHaveChatItem.Text = " :من " + item.Message;
// isHaveChatItem.ForeColor = Color.DarkCyan;
}
else
{
isHaveChatItem.Text = item.ToUser.UserName + " : " + item.Message;
// isHaveChatItem.ForeColor = Color.DarkRed;
}
isHaveChatItem.Value = item.MessageFlagID.ToString();
}
else
{
userListView.Items.Add(listViewItemTemp);
}
}
}
}
}
This function for Update UI >>> SetNewMessageOnUi
I Create Objects on Runtime.
this code is worked
userListView.Items.Add(listViewItemTemp);
and ListView Have Item But On UI Not set.
all objects in the UpdatePanle

C# TcpClient streamreader with eventhandler not all messages are processed

I'm reading continuously from a TcpClient streamreader.
The data coming from the stream is raw XML. There is no message framing. So there is now reliable method to know when the message is finished. Though I only have 3 XML messages coming from the server. But when they are coming is unknown. And I can't configure/program the server.
This is my code so far.
public void Start()
{
StreamReader reader = new StreamReader(_tcpClient.GetStream());
char[] chars = new char[Int16.MaxValue];
while (!_requestStop)
{
try
{
while ((reader.Read(chars, 0, chars.Length)) != 0)
{
string s = new string(chars);
s = removeEmptyChars(s);
if (s.IndexOf("<foo", StringComparison.OrdinalIgnoreCase) > 0 &&
s.IndexOf("</foo>", StringComparison.OrdinalIgnoreCase) > 0)
{
Console.WriteLine(s);
OnAlarmResponseComplete(new CustomEventArgs(s));
}
if (s.IndexOf("<bar", StringComparison.OrdinalIgnoreCase) > 0 &&
s.IndexOf("</bar>", StringComparison.OrdinalIgnoreCase) > 0)
{
Console.WriteLine(s);
OnAckComplete(new CustomEventArgs(s));
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//break;
}
}
reader.Close();
Console.WriteLine("Stopping TcpReader thread!");
}
Then in my main thread I'm processing the events. I'm adding them to a list.
Where I process the list.
When I'm debugging my application, I will be receiving 10 foo and 10 bar messages. And in my lists I have only 1 foo and 1 bar message stored.
Are the eventhandlers to slow to process this? Or am I missing something?
Here is the code you should use to cover all kinds of input issues (foo or bar received partially, foo and bar received together, etc..)
I can't say I approve using string parsing to handle XML content, but anyways.
private static string ProcessAndTrimFooBar(string s, out bool foundAny)
{
foundAny = false;
int fooStart = s.IndexOf("<foo", StringComparison.OrdinalIgnoreCase);
int fooEnd = s.IndexOf("</foo>", StringComparison.OrdinalIgnoreCase);
int barStart = s.IndexOf("<bar", StringComparison.OrdinalIgnoreCase);
int barEnd = s.IndexOf("</bar>", StringComparison.OrdinalIgnoreCase);
bool fooExists = fooStart >= 0 && fooEnd >= 0;
bool barExists = barStart >= 0 && barEnd >= 0;
if ((fooExists && !barExists) || (fooExists && barExists && fooStart < barStart))
{
string fooNodeContent = s.Substring(fooStart, fooEnd - fooStart + 6);
s = s.Substring(fooEnd + 6);
Console.WriteLine("Received <foo>: {0}", fooNodeContent);
OnAlarmResponseComplete(new CustomEventArgs(fooNodeContent));
foundAny = true;
}
if ((barExists && !fooExists) || (barExists && fooExists && barStart < fooStart))
{
string barNodeContent = s.Substring(barStart, barEnd - barStart + 6);
s = s.Substring(barEnd + 6);
Console.WriteLine("Received <bar>: {0}", barNodeContent);
OnAckComplete(new CustomEventArgs(barNodeContent));
foundAny = true;
}
return s;
}
public static void Start()
{
StreamReader reader = new StreamReader(_tcpClient.GetStream());
char[] chars = new char[Int16.MaxValue];
while (!_requestStop)
{
try
{
int currentOffset = 0;
while ((reader.Read(chars, currentOffset, chars.Length - currentOffset)) != 0)
{
string s = new string(chars).TrimEnd('\0');
bool foundAny;
do
{
s = ProcessAndTrimFooBar(s, out foundAny);
} while (foundAny);
chars = s.PadRight(Int16.MaxValue, '\0').ToCharArray();
currentOffset = s.Length;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//break;
}
}
reader.Close();
Console.WriteLine("Stopping TcpReader thread!");
}

Multithread with TCPclient

I do have a problem with a multithreaded TCPClient application, every Client object has a Thread that recievies and sends messages and a thread that handle the Tasks that should be handled (depending on the messages)... (for example creates and answer that the msg threads sends). But something is going wrong... the application almost allways uses 100% cpu (if any thread have a task, and thats most of the time). I also have a feeling that some threads get prioritised less then others (can see in some loggs that an operation takes longer in thread 1 then in thread 2 for exampel... Is there any nice way to handel this problem?
I would love some help or some hints!
Anything unclear just ask :)
Thanks! /Nick
//Waiting for TCP-connections and creating them as they arrive. Starts a Thread that handles the messages recieved and sent with this thread.
private void ListenForClients()
{
try
{
this.tcpListener.Start();
while (true)
{
TcpClient client = this.tcpListener.AcceptTcpClient();
Connection c = new Connection(this.parent);
connectionCollection.Add(c);
Thread clientThread = new Thread(new ParameterizedThreadStart(c.HandleClientComm));
threadCollection.Add(clientThread);
clientThread.Start(client);
}
}
catch (Exception e)
{
}
}
//Connection constructor, creates a ToDo-thread, this handles the messages (DB, Filewriting etc.) recieived and creats new ones to be sent.
public Connection()
{
this.todo = new ArrayList();
todoT = new Thread(handleToDo);
todoT.Start();
}
//Messagehandeling-thread
public void HandleClientComm(object client)
{
try
{
TcpClient server = (TcpClient)client;
NetworkStream ns = server.GetStream();
byte[] data = new byte[1024];
string input, stringData;
online = true;
DateTime lastTime = DateTime.Now;
while (true && this.online)
{
try
{
if (lastTime.AddMinutes(2) < DateTime.Now)
break;
data = new byte[1024];
if (ns.DataAvailable && ns.CanRead)
{
int recv = ns.Read(data, 0, data.Length);
if (recv > 0)
{
lastTime = DateTime.Now;
if ((byte)data[recv - 1] == (byte)255)
{
int cnt = -1;
for (int i = 0; i < recv; i++)
{
if (data[i] == (byte)254)
{
cnt = i;
break;
}
}
int nr = recv - cnt - 2;
byte[] tmp = new byte[nr];
for (int i = 0; i < nr; i++)
{
tmp[i] = data[cnt + i + 1];
}
string crc = Encoding.UTF8.GetString(tmp);
stringData = Encoding.UTF8.GetString(data, 0, cnt);
MsgStruct msgs = new MsgStruct(stringData);
msgs.setCrc(crc);
addTodo(msgs);
if (msgs.getMsg()[0] == 'T' && this.type == 1)
this.parent.cStructHandler.sendAck(msgs, this.ID);
Console.WriteLine(todo.Count);
}
}
}
if (parent.cStructHandler.gotMsg(this.ID))
{
MsgStruct tmpCs = parent.cStructHandler.getNextMsg(this.ID);
if (tmpCs.getMsg().Length != 0 && ns.CanWrite)
{
byte[] ba = Encoding.UTF8.GetBytes(tmpCs.getMsg());
if (tmpCs.getCrc() == "")
{
ulong tmp = CRC.calc_crc(ba, ba.Length);
tmpCs.setCrc(tmp.ToString("X"));
}
if (tmpCs.canSendByTimeout())
{
string crcStr = "?" + tmpCs.getCrc() + "?";
byte[] bb = Encoding.UTF8.GetBytes(crcStr);
crcStr = Encoding.UTF8.GetString(bb);
byte[] fullMsg = new byte[ba.Length + bb.Length];
bb[0] = 254;
bb[bb.Length - 1] = 255;
ba.CopyTo(fullMsg, 0);
bb.CopyTo(fullMsg, ba.Length);
string s = System.Text.UTF8Encoding.ASCII.GetString(fullMsg);
ns.Write(fullMsg, 0, fullMsg.Length);
if (!tmpCs.isAckNeeded())
parent.cStructHandler.removeNextMsg(this.ID);
}
}
}
}
catch (Exception e)
{
break;
}
}
ns.Close();
server.Close();
dead = true;
}
catch (Exception e)
{
dead = true;
}
}
//Todo-thread
public void handleToDo()
{
try
{
int cnt = 0;
while (true)
{
if (todo.Count > 0)
{
//SWITCH CASE FOR DIFFERENT MESSAGE TYPES, DOING TASKS DEPENDING ON WHAT ONES...
}
else
{
if (dead)
{
todoT.Abort();
todoT = null;
break;
}
}
}
}
}
Stop checking if data is available etc. and just let the read() block. That's how it's supposed to work!
If you want to write stuff to the socket, do it from another thread, (direct from parent thingy?), or change your design to use async reads/writes.
Looping around, polling stuff, sleep() etc. is just a waste of CPU and/or adding avoidable latency to your app.

multithreading webBrowser does not work

I am trying to code a multithreaded WebBrowser application.
The WebBrowser elements will just navigate to a given URL,
wait until it loads and then
click a button or
submit the form.
This should happen in a loop forever.
I'm using Microsoft Visual Studio 2010 and Windows Forms
Here's my code:
//added windows form 30 webbrowser object
//and now assigning them to an webbrowser array
wbList[0] = webBrowser1; wbList[1] = webBrowser2; wbList[2] = webBrowser3;
wbList[3] = webBrowser4; wbList[4] = webBrowser5; wbList[5] = webBrowser6;
wbList[6] = webBrowser7; wbList[7] = webBrowser8; wbList[8] = webBrowser9;
//etc. until:
wbList[29] = webBrowser30;
for (int i = 0; i < 30; i++)
{
wbList[i].ScriptErrorsSuppressed = true;
wbList[i].NewWindow += new CancelEventHandler(wb_NewWindow);
}
//********************************** creating threads here
Thread[] AllThread = new Thread[100];
int irWhichWbb = 0;
for (int nn = irDirectPostCount; nn < irNumber+1; nn++)
{
AllThread[nn] = new Thread(new
ParameterizedThreadStart(this.MultiThreadWebBrowser));
AllThread[nn].Start(nn.ToString() + ";" + irWhichWbb.ToString());
irWhichWbb++;
}
Application.DoEvents();
for (int nn = 0; nn < irNumber+1; nn++)
{ AllThread[nn].Join(); }
//Multi thread function
void MultiThreadWebBrowser(object parameter)
{
string srParam = parameter.ToString();
int i = Convert.ToInt32 (srParam.Substring(0,(srParam.IndexOf(";"))));
int irWhichWb = Convert.ToInt32(srParam.Substring(srParam.IndexOf(";")+1));
string hdrs = "Referer: http://www.xxxxxxxxx.com/xxxxxxxxxx.aspx";
try
{
wbList[irWhichWb].Navigate(srVotingList[i, 0], "_self", null, hdrs);
}
catch { }
try { waitTillLoad(irWhichWb); }
catch { }
waitTillLoad3();
}
// wait until webbrowser navigate url loaded
private void waitTillLoad(int irWhichLoad)
{
WebBrowserReadyState loadStatus;
//wait till beginning of loading next page
int waittime = 100000;
int counter = 0;
while (true)
{
try
{
loadStatus = wbList[irWhichLoad].ReadyState;
Application.DoEvents();
if ((counter > waittime) ||
(loadStatus == WebBrowserReadyState.Uninitialized) ||
(loadStatus == WebBrowserReadyState.Loading) ||
(loadStatus == WebBrowserReadyState.Interactive))
{
break;
}
counter++;
}
catch { }
}
//wait till the page get loaded.
counter = 0;
while (true)
{
try
{
loadStatus = wbList[irWhichLoad].ReadyState;
Application.DoEvents();
if (loadStatus == WebBrowserReadyState.Complete)
{
break;
}
if (counter > 10000000)
break;
counter++;
}
catch { }
}
}
private void waitTillLoad3()
{
DateTime dtStart = DateTime.Now;
while (true)
{
if ((DateTime.Now - dtStart).TotalMilliseconds > 4000)
break;
Application.DoEvents();
}
}
You don't say what kind of failure you get: "doesn't work" is not a good description.
I would first try with just a single thread. Does that work?
You have empty catch blocks, so you are silently ignoring some error conditions. This may well by hiding a problem.

Categories

Resources