开发者

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.

  1. Create an interface (we'll call it ISiemsen for now) that has a string property called "ShowTheResult"
  2. Now, in whatever object you want to be able to show the result (form, console app, web form...) you implement the ISiemsen interface
  3. 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)
  4. 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'.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜