|
1) the line is marked. see the comment in the OnReceive method. there is no other code (except for the OnSend method - but i don't thinkt that this one is the problem, cause it isn't used when the exception is thrown) that uses the array!
2) it was just an example. it may also happen with joins, quits etc. there has to be a way how to avoid that!?
|
|
|
|
|
1) What's sw? What's Addmsg?
2) Well, if you're using multiple threads to add and remove to the list of nicknames, you need a thread-safe structure or use a lock before reading and writing to the list. Have you considered looking at System.Collections.Generic.Dictionary<K, V>? It allows only unique keys. It will throw exceptions if you try to add duplicates. Like with any other structure, if you're using multiple threads to read and write to it, you'll need to do some locking to do this in a thread-safe way.
|
|
|
|
|
1) sw = form object
addmsg = delegate
guess there isn't the prob
2) yes, i've thought about it, but i don't get it working ;D well, guess i just have to try..
|
|
|
|
|
1) I bet the problem is in the Addmsg function. Can you post the code for that?
|
|
|
|
|
there is no function for that!
private delegate void Addmsgs(string msg);
private event Addmsgs Addmsg;
Addmsg = new Addmsgs(IRCStream);
IRCStream is a method, but it doesn't have anything to do with the array ;D
private void IRCStream(string line)
{
.
.
}
|
|
|
|
|
Yes, I meant the function that the Addmsg delegate is pointing to.
The exception may have been due to your passing a string[] to the Invoke method, which tries to call IRCStream(string), which doesn't take a string array (it only takes a string).
By the way, what does the exception message say? And what does the exception stack trace look like?
|
|
|
|
|
exception message: "ArgumentOutOfRangeException: InvalidArgument=Value of -1 is not valid for index"
exception line: "sw.Invoke(Addmsg, receivedtext);"
receivedtext is correct, when the error occurs, so the problem is probably the delegate.
<br />
private delegate void Addmsgs(string msg);<br />
private event Addmsgs Addmsg;<br />
<br />
Addmsg = new Addmsgs(IRCStream);
perhaps the problem is, as you mentioned some posts ago , that the socket is not thread safe. I googled and tried to find a solution to make the socket thread safe, but i didn't find anything, that could help me.
thanks for helping me so far
|
|
|
|
|
All that looks OK. It's a little round-about way of doing it (in C# 2 you can do anonymous methods that would save you the trouble of creating the delegate), but it should work nonetheless.
As a diagnostic, try commenting out the code in the IRCStream method. Does it still error out?
Also, is there an InnerException part of the error that occurs? If so, what is the stack trace on the InnerException of your ArgumentOutOfRangeException?
|
|
|
|
|
i found the error ;D indeed it was a mistake in the method. i just forgot an if stupid mistake.
but there's still another problem. if i join a big channel and there are a lot of messages coming in, in a short period of time, then it seems that i don't get all messages, but therefore some twice! i guess the solution would be to make the socket thread safe. how do i make the socket thread safe? as already mentioned, i don't find anything on the net that could help me. i hope you can help me with that too ;D
thanks so far!
|
|
|
|
|
I'm not sure that threading is really the problem. However, i If threading is indeed the problem, you can try putting a lock around your receiving code:
private byte[] data = new byte[4096];
private readonly object synchronizer = new object();
public void InitSocket()
{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Blocking = false;
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("194.124.229.58"), 6667);
client.BeginConnect(ipe, new AsyncCallback(OnConnect), client);
}
public void OnConnect(IAsyncResult ar)
{
Socket remote = (Socket)ar.AsyncState;
remote.EndConnect(ar);
remote.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnReceive), remote);
}
public void OnReceive(IAsyncResult ar)
{
lock(synchronizer)
{
Socket remote = (Socket)ar.AsyncState;
int received = remote.EndReceive(ar);
if (received == 0)
{
client.Close();
return;
}
string receivedtext = Encoding.Default.GetString(data, 0, received);
sw.BeginInvoke(Addmsg, new string[] { receivedtext });
remote.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnReceive), remote);
}
}
Now, some recommendations. First, I don't recommend using sw.Invoke or sw.BeginInvoke; use a System.ComponentModel.BackgroundWorker instead: it does all the "putting things on the right thread" for you using events for the "background work" (like your socket receiving), another event for progress changed (like your received text bit) and also an event for when the background work is finished.. Search the articles on this site for examples.
Another recommendation is, are you sure you need to code up this by yourself? Why not use a free, open source library someone's already written, such as SmartIrc4Net[^].
|
|
|
|
|
donjubs wrote: sw.Invoke(Addmsg, new string[] { receivedtext }); // exception when data is full
This line looks completely wrong to me. You've already allocated a new string in the line above, why do you need to create an array of strings to be passed up to the display and put the new string in it?
The exception with your code is in the form code. Probably something to do with where you are displaying the string. Do you remove the lines from the top of the display window? What type of a control are you using?
Oh, there are many other questions to ask, but the only other one I will ask is: Where is the error handling for these methods?
Phil
|
|
|
|
|
well, i changed it to "sw.Invoke(Addmsg, receivedtext);" seems to improve it a little, but doesn't solve the problems.
i have to use invoke to display the messages in a richtextbox and invoke requires a delegate => Addmsg. so i don't think that there's still a mistake in it.
form code (i think that you mean that one):
<br />
private void IRCStream(string line)<br />
{<br />
string[] msgs = line.Split('\r');<br />
foreach (string msg in msgs)<br />
{<br />
sw.RTBOX.Text += msg;
}<br />
}<br />
so i don't think that there's the problem.
kind regards
|
|
|
|
|
Hi All,
I have a form with two panels in one i have a treeview and in another a listview , when i click on a treeview node it's selected but when i click on list view it's not selected.
Now , i want to change the background color of the selected node and want it to remain until i select another node.
If anyone has any idea , i will be thankful.
Praveen Sharma
|
|
|
|
|
Have you considered setting treeview.HideSelection to false?
|
|
|
|
|
I'm at a breakpoint with my architecture and could use some guidance in finishing up my vision. I will give a rundown of the current architecture so far:
This is a plug-in architecture, that automates the loading and un loading of plug-ins for the users and developers. By using a defined interface and custom attributes my architecture will auto load plug-ins without the use of ini files or configuration files.
The current issue I have is my security and applying security filters to screens as they display. What basically will happen is an admin will setup security and access points for roles. Roles are then assigned to a user. What I need is to be able to disable, hide, unhide or re-enable elements on the form at the time the page is loaded based on that users security role. This is simple if I have every developer call a set of security procedures, but what I want is the framework to automatically do this for the developer.
The one idea so far is the use of “Application Event Handler” which is looking for a certain windows message to be sent.
I was wondering if anyone else had any other ideas that might be worth looking into. ( IE: any patterns or such)
Thanks for the Help.
Sal
|
|
|
|
|
Instead of calling my stored procedure n number of times in a loop how can i call the stored procedure once. I don’t want to pass the values as varchar as it is not a fixed length. I am not going to have high volume data and hence sqlbulkcopy is not required. Is there another way?
|
|
|
|
|
Civic06 wrote: Instead of calling my stored procedure n number of times in a loop how can i call the stored procedure once. I don’t want to pass the values as varchar as it is not a fixed length. I am not going to have high volume data and hence sqlbulkcopy is not required. Is there another way?
Start by explaining wtf it is your doing.
Why are you calling it in a loop?
If it needs to be in a loop why do you want to call it just once?
Why do you not want to use a variable length field?
From what your saying the answer is use x if you need x otherwise use y if you need y...
|
|
|
|
|
Civic06 wrote: mber of times in a loop how can i call the stored procedure once
Don't put your stored procedure in the loop if you only want it called once.
Hogan
|
|
|
|
|
I have a SP which takes in two parameters. One parameter is fixed length. The other depends on what the user has selected from the checkboxlist control. I could either put this in a loop sending the first parameter and the second (depending on how many values were checked in the checkboxlist). OR
I could concatenate the second parameter and send it as a string (however, i don't know how long this string can get...as varchar is max of 8000)
OR
is there another way?
|
|
|
|
|
With Sql Server 2005 you can varchar(MAX) to get unlimited space. if your on 2000 or below then yep you have to chunk it.
|
|
|
|
|
I've never had a need to use conditional compilation before, so I have very little experience with it. Is there a way to do your #define directivess in a single place?
I want to set 2 define variables, and include certain menu items in the presents of each. (different features allowed in different editions of the same project). But I would like to avoid having my #define directives in the designer file where the autogenerated code is and the forms code file where the event handlers are. Is there a way to do this? I know this approach has other problems as well, any changes that alter the designer file will toss my changes to the wind for one thing.
If not I can of course build and add my menu items manually outside of the designer file, but it would be nice to have them there at design time too.
|
|
|
|
|
BoneSoft wrote: Is there a way to do your #define directivess in a single place?
In the properties for the project. Right-click the project in the solution explorer. Click Properties from the menu. In the new window that opened up select the "Build" tab and look for "Conditional Compilation Symbols"
BoneSoft wrote: But I would like to avoid having my #define directives in the designer file where the autogenerated code is and the forms code file where the event handlers are
You can't put them in there anyway - Visual Studio will overwrite them.
BoneSoft wrote: Is there a way to do this?
You could put them in the form's load and have it remove the UI elements you don't want if you want the menu items available at design time.
Upcoming events:
* Glasgow: Mock Objects, SQL Server CLR Integration, Reporting Services, db4o, Dependency Injection with Spring ...
"I wouldn't say boo to a goose. I'm not a coward, I just realise that it would be largely pointless."
My website
|
|
|
|
|
Yeah, I know. I was looking at loading them after startup. But then I have ordering issues. Removing them on load is a good idea. And I never noticed the conditional section in the project properties. Thanks.
|
|
|
|
|
Hi,
you dont need to include #define statements at all, you can define symbols in the
project properties dialog, under Build/General/Conditional Compilation Symbols.
That is what I do when I run two different projects (one .NET 1.1, one .NET 2.0)
on the same source files, to make sure my code works for both; doing so I can compensate
for slight differences between both .NET versions (e.g. method name changes in Dns class).
So I suggest you use Designer to set up your project in one way, then add #if #endif blocks
to modify it in your code files (e.g. after InitializeComponents) for the alternative way;
now change your defines manually in the property dialog; you could even add configurations
(say multiple debug configurations with different #defines).
|
|
|
|
|
Actually, I'm thinking about having different project files for each edition while keeping the same code. In this situation, it seems a more reasonable approach than moving shared functionality to a control library. Thanks for the suggestion.
|
|
|
|
|