Trying to create a method that can write to Console or Form application
I'm working on a general server and a client programs. The problem I'm facing is when I'm in the OnDataReceived in my client and server I don't know what to do with the data. Ideally it should output the received data into a window but I don't know if it will be a Form or Console application. So the question is how do I create a general method that can handle both or if that is not possible what should I do instead?
The code I'm working with:
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
Decoder decode = Encoding.Default.GetDecoder();
int charLength = decode.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
String szData = new String(chars);
//Handle Message here
WaitForData();
And the socket packet class:
class SocketPacket
{
public Socket m_currentSocket开发者_如何转开发;
public byte[] dataBuffer = new byte[1024];//Buffer to store the data by the client
public SocketPacket(Socket socket)
{
m_currentSocket = socket;
}
}
PS. I don't know if needs to be known but I'm doing asynchronous Client/Server.
Your communication classes shouldn't care what happens to the data they receive. Instead, they should either make the data available to a class that wants it. One way to do so would be to provide a getData() method, which received data and then returned it to the caller. Even better would be to provide a DataArrived event, which was fired whenever you received data. That way, any number of consumers could listen for data, but your communication code doesn`t have to know which classes are listening or what they plan to do with the data.
EDIT:
A simple example:
public class MyClassWithEvent
{
public delegate void DataArrivedDelegate(string data);
public event DataArrivedDelegate DataArrived;
public void GetSomeData()
{
// Communication code goes here; stringData has the data
DataArrivedDelegate handler = DataArrived;
if (handler != null)
{
// If you want to raise the event on this thread, this is fine
handler(stringData);
}
}
}
In your listener class:
public MyListener
{
public MyListener(MyServer server)
{
// Sets MyListenerMethod to be called when DataArrived is raised
server.DataArrived += MyListenerMethod;
}
public void MyListenerMethod(string data)
{
// Do something with the data
Console.WriteLine(data);
}
}
Fire an event with the string? I would help if the data buffer string was a member of the socket object - then you could fire an event with just the socket object & your event-handler, whatever it turns out to be, would have everything it might need to decide what to do with the data.
Rgds, Martin
I would create an interface where I can write the event information, something like IEventSink. So the OnDataReceived works with an instance of IEventSink and call a Write method on it. Then I will have 2 implementation of the interface: one that write on the console and one that write on a form.
You can try to implement strategy
interface IOutputStrategy
{
void Output(string message);
}
class ConsoleOutput:IOutputStrategy
{
public void Output(string message)
{
Console.Writeline(message);
}
}
class FormOutput:IOutputStrategy
{
public void Output(string message)
{
// output where you want
}
}
and on Server / Client you will proeprty of type IOutputStrategy
//Server
IOutputStrategy instance = new ConsoleOutput();
//Client
IOutputStrategy instance = new FormOutput();
And then in OnDataReceived callback you can use current IOutputStrategy instance to output message
instance.Output(szData);
Hope it helps
This is a good location for Dependency Injection.
- Create an interface (we'll call it ISiemsen for now) that has a string property called "ShowTheResult"
- Now, in whatever object you want to be able to show the result (form, console app, web form...) you implement the ISiemsen interface
- Inside the property set for "ShowTheResult" you assign the value to whatever fills the need for that object. (If it is a console you execute a console.WriteLine(value), if it is a form, you assign the value to a textbox)
Change your worker process to accept reference to your worker function and let it send the response where ever it needs to go.
protected void getResults(ISiemsen siemens ... ) { SocketPacket theSockId = (SocketPacket)asyn.AsyncState; int iRx = theSockId.m_currentSocket.EndReceive(asyn); char[] chars = new char[iRx + 1]; Decoder decode = Encoding.Default.GetDecoder(); int charLength = decode.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0); String szData = new String(chars); WaitForData(); //Handle Message here siemsen.ShowTheResult(theResult); }
Using this technique the UI element doesn't know or care where the data comes from and worker process doesn't know or care where the going... it is 'loosely coupled'.
精彩评论