|
|
Okay understand
But will i have to use two streams to be abled to send data in both directions?
Best Regards
SnowJim
|
|
|
|
|
A memorystream does not go anywhere, except to memory, so I am unsure what you could mean by "send data in both directions". In any case, if you need to both read from a stream, and write to a stream, you would normally use 2 streams to do that.
my blog
|
|
|
|
|
Hey!
I need to write to a MemoryStream from one part of my program and in another i whant to read this data form the MemoryStream.
This is how i write byte to the MemoryStreams
<br />
public override void WriteByte(byte value)<br />
{<br />
try<br />
{<br />
s.WriteByte(value);<br />
<br />
foreach (UnitStream unit in StreamCollection)<br />
{<br />
if (unit.getUnitStream.CanWrite)<br />
unit.getUnitStream.WriteByte(value);<br />
}<br />
}<br />
catch (Exception ex)<br />
{<br />
addError("Error in PhoneConnector - MutliStream - Write : " + ex.Message);<br />
}<br />
}<br />
When i am pasing data in to this function it writes it to the MemoryStreams(collection), but when i am lookin on the MemoryStreams ther is no data written to them?
I m a doing wrong?
BestRegards
Jimmy
|
|
|
|
|
|
Like this?
<br />
public override void WriteByte(byte value)<br />
{<br />
try<br />
{<br />
s.WriteByte(value);<br />
<br />
foreach (UnitStream unit in StreamCollection)<br />
{<br />
if (unit.getUnitStream.CanWrite)<br />
unit.getUnitStream.WriteByte(value);<br />
unit.getUnitStream.Flush()<br />
}<br />
}<br />
catch (Exception ex)<br />
{<br />
addError("Error in PhoneConnector - MutliStream - Write : " + ex.Message);<br />
}<br />
}<br />
But is not Flush clearing the buffert?
I have tryed to step thow this funktion and then
unit.getUnitStream.WriteByte(value);
is done there is still no data in the the stream(unit.getUnitStream(MemoryStream)) Can Flush realy help me with this problem?
Best Regards
SnowJim
|
|
|
|
|
Calling Flush has no effect when using a MemoryStream , since any data written to a MemoryStream is written into RAM.
www.troschuetz.de
|
|
|
|
|
Calling Flush has no effect when using a MemoryStream , since any data written to a MemoryStream is written into RAM.
www.troschuetz.de
|
|
|
|
|
But why are the data not written to the memory stream? or is it not posible to see in debug what the memorystream is containing?
Maby i will have to read it to see it?
Best Regards
Jimmy
|
|
|
|
|
It's a pretty strange problem.
Where and how do you initialze your StreamCollection?
www.troschuetz.de
|
|
|
|
|
Your memorystream is probably still positioned at the end after you do your write. You can't read from it until you set the Position to an earlier point in the stream.
To see if you are successfully writing to the stream, check that the Length and Position properties are changing as you write.
|
|
|
|
|
Yes, the Length and position is not moved when writing to it!
Also, if i write to the stream, then the position will be set where the writer ends(say it writes 32 byt and stops on position 31), when i need to read it will read position 32 and forth.
I need it to read from position 0, and to manage this i will have to change the position. But if my unit that writes to this stream needs to write then the position will be pointing on the wrong element if i havent read throw all the elements with my reading unit.
How is this sopose to work?
I need the writing unit to write in a line and i need the reading unit to read any not readed data from the beginning and discarding the readed data. Is this not realy how the stream work?
Best Regards
Jimmy
|
|
|
|
|
There is definately something wrong if the Length and Position do not change after a write. I don't know what is wrong. Try looking at the data in the command window before and after a write. Use the exact same syntax in the command window as in the program for accessing the memory stream.
Maybe there is something wrong in the code where the memory streams are instanciated.
Yes, you need to manage the positions you read from separately. You could do so in a class you derive from memory stream and manage the positions so you don't have to keep track at both ends.
|
|
|
|
|
Thanks again for all the info!
I have made a class that derives from regular Stream and in this class i have addad a MemoryStream that will be the main stream.
<br />
#region Using directives<br />
<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using System.IO;<br />
<br />
#endregion<br />
<br />
namespace PhoneConnector<br />
{<br />
public class MemoryEventStream<br />
{<br />
Stream mainStream;<br />
int readPosition = 0;<br />
<br />
public MemoryEventStream()<br />
{<br />
mainStream = new MemoryStream();<br />
}<br />
}<br />
}<br />
I will do all the override functions with this mainStream.
There is one problem:
Say that i have added 40 bytes to the mainStream(MemoryStream).
When the reading unit have readed some bytes i need to remove this bytes. How could o do this?
I can only find flush but this will remove all the bytes.
Maby the memorstream is itself removing this bytes that have been readed? in that case the readPosition will be wary big?
Best Regards
Jimmy
|
|
|
|
|
Snowjim wrote:
Maby the memorstream is itself removing this bytes that have been readed? in that case the readPosition will be wary big?
The MemoryStream does not remove bytes when read. If you want this behavior, then you will have to code it yourself, adjusting the read and write pointers when you remove data from the stream.
|
|
|
|
|
But then the stream buffert will become very big? won´t the system memory run out?
How does regular streams handle this?
|
|
|
|
|
.Net memorystreams will increase in size if you keep writing to them (unless you use a fixed length byte array as its buffer).
If you want to write to the end and read from the front without running out of memory, you can manage your own byte arrays. There are several ways I can think of to manage array size:
1. When you read from the front of the stream, move the content: array.Copy(buf, readlength, buf, remainingLength). This technique might not perform well depending on the implementation of array.Copy.
2. Use a short list of byte arrays for the stream. When your write would go past the end of the array, create a new array (or manage a pool of existing arrays) to put the overflow in. Add the new array to a collection. When you read the past the end of an array, you can remove it from the collection.
3. Use a circular system. When your write would go past the end of the byte array, use any unused space at the front of the array (unused, since you have already read the data and moved the read position further along the array).
I don't know how .Net handles these issues in streams. I would probably try method 2 above, since it doesn't require collision testing like method 3. Method 2 is also easy to optomize to various buffer sizes and could perform quite well. Method 1 could work also, but I don't know how good the performance is of Array.Copy.
|
|
|
|
|
This is very good info!
I have tryed some more.
And right now i have built in an ArrayList in my Stream.
When adding a byte i am using
<br />
StreamCollection.Add(value);
OnReceivedData(new EventArgs());
and when a unit is reading i am using :
<br />
int tmpData = (int)((byte)StreamCollection[0]);<br />
StreamCollection.RemoveAt(0);<br />
return tmpData;<br />
Maby this is a slow way to handle it?
2. Use a short list of byte arrays for the stream. When your write would go past the end of the array, create a new array (or manage a pool of existing arrays) to put the overflow in. Add the new array to a collection. When you read the past the end of an array, you can remove it from the collection.
I started with this but then i thougt that it maby was the same speed if i just place the bytes in the ArrayList?
Or will 2# be faster?
If i have got this 2# right
Then i first need a collection(ArrayList)
int this Collection i will store smal byte arrays like byte[128] or somthing like that.
Then when i have i howl byte buffert(byte[128]) full then i will have to create a new byte array that i write to and place this on the second place in the Collection.
When the reader have readed the first byte buffert in the collection it will be removed
Collection.removeat(0); and then it will begin read on the next byte array.
Will this realy be faster then just adding the bytes to the ArrayList?
Its important that you can work against this stream as any regular stream. It is posible that it will be connected to controls that reads from streams. Will this be posible if I maintain the override funktion of Stream? like WriteByte(), ReadByte(); and so on?
Best Regards
Jimmy
|
|
|
|
|
Snowjim wrote:
If i have got this 2# right
Then i first need a collection(ArrayList)
int this Collection i will store smal byte arrays like byte[128] or somthing like that.
Then when i have i howl byte buffert(byte[128]) full then i will have to create a new byte array that i write to and place this on the second place in the Collection.
Yes this was my intention. Although, I was thinking of a default size of the byte arrays to be maybe 1024 or 2048 bytes. The performance could be optimized by changing the array sizes to best fit the expected use. My idea is that you want only a few byte arrays at any one time. I think it is much faster to access a byte in a byte array than a member of an arraylist, but I haven't checked. The only performance problem comes when you need to add a new byte array to the arraylist, but if it causes too much performance problem, it could be optomozed with a pre-existing pool of byte arrays which you add or remove from the arraylist.
If using an arraylist provides good enough performance, then use it! Some time later, the performance might not be good enough for a project that needs more speed, so then you optimize your class with a new internal implementation.
Snowjim wrote:
Its important that you can work against this stream as any regular stream. It is posible that it will be connected to controls that reads from streams. Will this be posible if I maintain the override funktion of Stream? like WriteByte(), ReadByte(); and so on?
The stream object inherits from MarshalByRefObject and implements iDisposable, so I don't know what you mean by "connected to controls". Your class should work fine if you have implemented the major stream methods.
|
|
|
|
|
Hi,
In our project we want to be able to load a report from file,
try to rebuild the query (adapt if necessary)
create a dataset from that query
set the dataset as source of the report.
Now I can create the query (more or less ), but when I set the dataset to the datasource the report is still what it was in design.
I do something like this:
<br />
string query = "Select " + fields + " FROM " + tables + " " + whereclause + " " + groupby;<br />
txtbox_query.Text = query;<br />
DataBaseConnector.EXECUTE_STATUS dbstat = dbconnector.ExecuteSelect(query);<br />
if(dbstat == DataBaseConnector.EXECUTE_STATUS.EXECUTE_SUCCESFUL){<br />
txtbox_status.Text = "The query " + txtbox_query.Text + " executed correctly.";<br />
txtbox_status.ForeColor = System.Drawing.Color.Green;<br />
reportdoc.SetDataSource(dbconnector.GetDataSet());<br />
dg_select.DataSource = dbconnector.GetDataSet();<br />
}
else{<br />
txtbox_status.Text = "The query " + txtbox_query.Text + " failed. " + dbconnector.GetLastErrorMessage();<br />
txtbox_status.ForeColor = System.Drawing.Color.Red;<br />
}
crv_test.ReportSource = reportdoc;<br />
the dataset is correctly set in my datagrid, but not in my report.
the report is loaded from file and the query is generated from that reportobject.
I hope somebody can help me
tnx!
No hurries, no worries.
|
|
|
|
|
Hey Guys i'm currently working on a school assignment. So far i have created a combo box, text box and a datagrid. when the user selects which database to list using the combo box (say they choose movies) it then lists the movies database in the datagrid then when the user types a in the text box it will only show the movies or items starting with a or A. OKAY now the fun begins :P now i want it so when the user clicks on the item in the datagrid it fills the text box with that name?
can someone please help me or show me a link to a tutorial
|
|
|
|
|
i succeeded to create multithreaded server that can accept multiple clients connection while running alright and every client can send to the server messages but when i try to send from the server message for all clients connected now it through and exception and it doesn't send anything i want to handle the connection for all users to send them back messages for all of them something like hashtable to handle tcp clients who are now connected any one knows how to do it .
my code is
<br />
private Hashtable connections; <br />
public void runserver()<br />
{<br />
connections = new Hashtable();<br />
TcpListener server;<br />
try<br />
{<br />
server = new TcpListener(5151);<br />
server.Start();<br />
do<br />
{<br />
try<br />
{<br />
if(counter < 1 || counter == 1)<br />
{<br />
generalchat.Items.Add("Waiting for connection");<br />
}<br />
<br />
Socket connection = server.AcceptSocket();<br />
Thread Anotherthread = new Thread(new <br />
ThreadStart(HandleConnection));<br />
connections.Add(Anotherthread, connection);<br />
++counter;<br />
generalchat.Items.Add("Connection " + counter + " Recieved");<br />
Anotherthread.Start();<br />
}<br />
catch (Exception)<br />
{<br />
break;<br />
}<br />
} while (true);<br />
}<br />
catch (System.Exception caught)<br />
{<br />
MessageBox.Show(caught.Message);<br />
}<br />
}<br />
private Hashtable myclients;<br />
private TcpClient clients;<br />
private void HandleConnection()<br />
{<br />
Socket connection = connections[Thread.CurrentThread] as Socket;<br />
NetworkStream socketstream = new NetworkStream(connection);<br />
BinaryReader reader = new BinaryReader(socketstream);<br />
BinaryWriter writer = new BinaryWriter(socketstream);<br />
writer.Write("Server : " + "Welcome Client");<br />
myclients = new Hashtable();<br />
clients = new TcpClient();<br />
myclients.Add(connection,clients.GetStream());<br />
string message = "";<br />
do<br />
{<br />
message = reader.ReadString();<br />
if(message == "terminate")<br />
{<br />
generalchat.Items.Add("Client Terminated the connection");<br />
--counter;<br />
break;<br />
}<br />
if(message.IndexOf("@") != -1)<br />
{<br />
clientTable.Add(this.flush(message),splittedwords[1].ToString());<br />
generalchat.Items.Add(this.flush(message) + " : Already Connected");<br />
}else<br />
generalchat.Items.Add(message);<br />
<br />
} while (connection.Connected);<br />
}<br />
any one knows how please
Miss With The Best And Die Like The Rest
|
|
|
|
|
You'd have to iterate through the hashtable's keys and get the client sockets. You'd then have to get the NetworkStream and write to it.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
I'm having quite a problem figuring this out. In the microsoft SDK i found some functions to make controls transparent:
<br />
SetStyle(ControlStyles.SupportsTransparentBackColor, true);<br />
this.BackColor = Color.Transparent;<br />
and they said something about it had to be placed in the constructor????? Kinda lost. Can i apply this to the standart listboxes in the .Net framework, or do i have to create my own control which inherits the functions of a listbox?
thanks in advance!
|
|
|
|
|
can't you just change the opacity?
|
|
|
|