|
Hello
theonewithtom wrote: I would like these events to be raised on the main thread
You stil can do something like that, but why?!! Why not using Asynchronous sockets?
Search MSDN for BeginAccept() method
Regards
|
|
|
|
|
Thanks, I've been having a bit of a problem with the async read method, so is it possible to do it without using this?
Many Thanks
Tom
|
|
|
|
|
Hello
Of course you can using a single thread. Actually what happens behind the scene is that the asynchronous call makes an anonymous worker thread for you that will carry the action. When that thead receives anything it will call the Callback method that you will provide as a delegate.
Take a look t this code, copied from MSDN:
IPHostEntry lipa = Dns.Resolve("host.contoso.com");
IPEndPoint lep = new IPEndPoint(lipa.AddressList[0], 11000);
Socket s = new Socket(lep.Address.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp);
try{
s.Bind(lep);
s.Listen(1000);
while(true){
allDone.Reset();
Console.WriteLine("Waiting for a connection...");
s.BeginAccept(new AsyncCallback(Async_Send_Receive.Listen_Callback), s);
allDone.WaitOne();
}
}
catch (Exception e){
Console.WriteLine(e.ToString());
}
All you have to do is to provide the callback method.
Regards
-- modified at 16:16 Sunday 20th August, 2006
Sorry, I just noticed you said "async" not "sync". What's exactly your problem with the above approach??
Regards
|
|
|
|
|
Maybe my question is simpler than I first thought
> When that thead receives anything it will call the Callback method that you will provide as a delegate.
Do you mean it is possible to call a delegate from a worker thread that will execute on the main thread?
Many Thanks
Tom
|
|
|
|
|
Hello
theonewithtom wrote: call a delegate from a worker thread that will execute on the main thread?
No! You don't bother yourself with multithreading. You just make a method to handle the data -called callback method- which will be excuted on the main thread. Once you want to listen call the BeginAccept() or BeginReceive -accroding to how you want to handle your sockets-, and all the listening and reading time is done on another thread invisible to you. You don't make any threads. It will be made for you and you can't access it. Everything you write will be excuted on the main thread -which if you don't handle properly may make your UI freezes-.
Regards
|
|
|
|
|
Okay, I'll go through why I think I need multithreading. My listener code is below:
<br />
private void run() {<br />
<br />
NetworkStream ns = new NetworkStream(clientSocket);<br />
BinaryFormatter bf = new BinaryFormatter();<br />
<br />
while (true) {<br />
<br />
Message m = bf.Deserialize(ns);<br />
<br />
messageRecieved(this, m);<br />
}<br />
<br />
}<br />
As far as I can tell, it is not possible to do the deserialize and use the async read methods.
Any thoughts?
Many Thanks
Tom
|
|
|
|
|
Hello
Well if the asynchronous method troubles you and you want to multithread -The way I like BTW-. Then you should use Invoke() . Have a look
delegate void MessageReceivedDel(Message m);
private void run() {
NetworkStream ns = new NetworkStream(clientSocket);
BinaryFormatter bf = new BinaryFormatter();
MessageReceivedDel messageRecieved = new MessageReceivedDel(MessageReceivedMethod);
while (true) {
Message m = bf.Deserialize(ns);
messasgeReceived(m);
}
}
private void MessageReceivedMethod(Message m)
{
}
Remember that MessageReceivedMethod is a member method of you main form class.
Regards
|
|
|
|
|
|
Hi,
Try this code. Maybe will help.
<br />
Socket m_tcpListener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);<br />
m_tcpListener.Bind(new IPEndPoint(IPAddress.Any,20000));<br />
Socket client = m_tcpListener.Accept();<br />
Thread clientThread = new Thread(new ThreadStart( (new ServeClient(client)).Start ));<br />
clientThread.Start();<br />
<br />
class ServeClient<br />
{<br />
private Socket client = null;<br />
<br />
public ServeClient(Socket client)<br />
{<br />
this.client = client;<br />
}<br />
<br />
public void Start()<br />
{<br />
}<br />
}<br />
I created the class named ServeClient in which you cand do all your work. In my example for each client a new thread is launched. If you want to limit the number of clients that connect at the same time to your server (and the number of threads) you can call the Listen method of the socket.
Hope it helps
Do your best to be the best
|
|
|
|
|
How Can I build A setup from my project That when somebody wants Install my program in the Wiondows whithout .NetFrameWork The .NetFramework Install Automatically ?? !! ?? !! ??
->(Use .NetFrameWork 1.1)<-
With Thanks
MHF
-- modified at 8:51 Sunday 20th August, 2006
MHF
|
|
|
|
|
Err, wouldn't that turn a 1MB app into a 24MB app?
But yeah, i wanna know how you do somehting like this as well, but maybe just give out a message and redirect them to the download.
|
|
|
|
|
Size Isn't Important
I want do This Automatically
With Thanks
MHF
-- modified at 9:13 Sunday 20th August, 2006
|
|
|
|
|
|
|
Hello
1- RightClick on your setup project's name in the solution explorer
2- Click on Properties
3- Click on settings
4- Press "Prerequisite" button
5- Check .Net Framework
6- Check Windows Installer -recommended but not required-
7- check "download from same location as my application
8- Done!
Regards
|
|
|
|
|
|
Okay, well i got my app working, so thanks for any previous help.
I have the app open a file and build a treeview based on its contents. I have a button for this, which is redirected to a void containing all the code on building the treeview.
I also have a menu, which i named File inside this menu is a menu item called open. Quite simple so far, you click open, that also takes you to the void where the treeview is built.
BUT, when i click on File-Open, after the first node is added, it should a a subnode but instead i get the error message 'Object referemce not set to an instance of an object'
When i use the button i get no such error message and everything works perfectly. I just don't understand it.
|
|
|
|
|
I suggest you attach a debugger and find out what is null...
|
|
|
|
|
Its just adding a node, but its exaclty the same code that the button uses.
I create an object oNode, then go:
this.treeView1.SelectedNode.Nodes.Add(oNode)
When i use the button it works, its just when i use the menu item. It makes no sense.
|
|
|
|
|
Here is the relevant code upto the problem, and i don't wanna here nothin' about how messy the code is, or how i should use xml, cuz i don't wanna.
//Don't ask why its menu item 5
//This is the 'Open' menu item
void MenuItem5Click(object sender, System.EventArgs e)
{
this.Open();
}
//This is the button 'Load'
void Button1Click(object sender, System.EventArgs e)
{
this.Open();
}
//And this is the void they're pointing to
void Open()
{
this.treeView1.Nodes.Clear();
this.openFileDialog1.InitialDirectory = @"C:\Program Files\Datel\Action Replay Code Manager\local_codelists\";
this.openFileDialog1.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
this.openFileDialog1.Title = "AR DS Code Editor";
this.openFileDialog1.ShowDialog();
if(this.openFileDialog1.FileName.Length > 0)
{
string FileLine;
FileStream FS = File.Open(this.openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
StreamReader SR = new StreamReader(FS, true);
FileLine = SR.ReadLine();
while(FileLine != null)
{
int trim = FileLine.IndexOf("<");
FileLine = FileLine.Remove(0, trim);
switch(FileLine)
{
case("<game>"):
{
string oName = SR.ReadLine();
int indexOfStart = oName.IndexOf('>');
int indexOfEnding = oName.LastIndexOf('<');
oName = oName.Substring(indexOfStart+1, indexOfEnding-indexOfStart-1);
string oID = SR.ReadLine();
indexOfStart = oID.IndexOf('>');
indexOfEnding = oID.LastIndexOf('<');
oID = oID.Substring(indexOfStart+1, indexOfEnding-indexOfStart-1);
Cheat oNode = new Cheat();
oNode.sType = "game";
oNode.sName = oName;
oNode.sID = oID;
oNode.Text = oName;
this.treeView1.Nodes.Add(oNode);
oNode.ForeColor = Color.Red;
this.treeView1.Select();
break;
}
case("<cheat>"):
{
string oName = SR.ReadLine();
int indexOfStart = oName.IndexOf('>');
int indexOfEnding = oName.LastIndexOf('<');
oName = oName.Substring(indexOfStart+1, indexOfEnding-indexOfStart-1);
string oCode = SR.ReadLine();
indexOfStart = oCode.IndexOf('>');
indexOfEnding = oCode.LastIndexOf('<');
oCode = oCode.Substring(indexOfStart+1, indexOfEnding-indexOfStart-1);
Cheat oNode = new Cheat();
oNode.sType = "cheat";
oNode.sName = oName;
oNode.sCode = oCode;
oNode.Text = oName;
this.treeView1.SelectedNode.Nodes.Add(oNode); //This is where the error occurs for the menu item
oNode.ForeColor = Color.LimeGreen;
break;
}
-- modified at 17:08 Sunday 20th August, 2006
|
|
|
|
|
The Undefeated wrote: this.treeView1.SelectedNode.Nodes.Add(oNode); //This is where the error occurs for the menu item
Then just check why SelectedNode is null.
I suspect it has maybe some to do with: TreeView.HideSelection property.
|
|
|
|
|
I'll check that, but it should'nt make a difference, its the same code.
Its like, hey this is a nice pen, and you try it out, it works yay!
You go home, it doesnt work anymore.
You go back to where you found it, it works again!
Its madness.
|
|
|
|
|
No setting it to true, removing it all togeather, it made no difference.
|
|
|
|
|
Hi
Don't use SelectedNode property to get the root node.As you can see selectedNode can be null depending on the way you interact with your UI.
It's better to get a reference to the root node when it's created and hold it until it might be needed.
You can use a map with a unique key to perform that if you are loading parent nodes up front.
For example:
<br />
IDicitonary parents=new Hashtable();<br />
foreach(FileLine fl in GetFileLines())<br />
{<br />
TreeNode fileLineNode=new TreeNode();<br />
fileLineNode.Text=fl.Name;<br />
parents.Add(fl.ID,fileLineNode);<br />
}<br />
later in your code you can reach a parent node using it's ID
Or if you are loading children nodes exactly after a parent node there is no need to use a map.
For example:
<br />
foreach(FileLine fl in GetFileLines())<br />
{<br />
TreeNode parentNode=new TreeNode();<br />
foreach(Game g in GetGames(fl))<br />
{<br />
TreeNode gameNode=new Node();<br />
parentNode.Nodes.Add(gameNode);<br />
}}<br />
I recommend you to use a xml file instead of a plain text file something like:
<File>
<FileLine>
<Game>
</Game>
</FileLine>
</File>
Then you can take advantage of XML Document object to open your file and query your nodes
-- modified at 2:10 Monday 21st August, 2006
|
|
|
|
|
I can't change the style of the xml file it has to stay the way it is.
I no longer do SelectedNode.Nodes.Add()
I the root node being a game, it is now gNode and all cheats etc are added to that.
Still have the problem though.
|
|
|
|