0

2 つの方法がprepareData()ありsendData()ます。

    private void prepareData(string longFileName, string shortFileName)
    {
        try
        {
            byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName);
            byte[] fileData = File.ReadAllBytes(longFileName);
            byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
            byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
            fileNameLen.CopyTo(clientData, 0);
            fileNameByte.CopyTo(clientData, 4);
            fileData.CopyTo(clientData, 4 + fileNameByte.Length);
        }
        catch
        {
        }
    }

    private void sendData(string clientIP, int clientPort, byte[] clientData)
    {
            TcpClient clientSocket = new TcpClient(clientIP, clientPort);
            NetworkStream networkStream = clientSocket.GetStream();
            networkStream.Write(clientData, 0, clientData.GetLength(0));
            networkStream.Close();
            clientSocket.Close();
    }

prepareData()プログラムのロード時に呼び出されます。これは大変な作業です。

sendData()は数秒ごとに呼び出され、byte[] clientDatafromを送信する必要がありますprepareData()

byte[]最初の方法から 2 番目の方法に移行するにはどうすればよいですか?

4

3 に答える 3

0

時間に依存しない方法で、クラスの 2 つのメソッド間でデータを共有しようとしていると思います。次のような例に基づいて、クラスのグローバル構造を作成する必要があります。

ConcurrentQueue<byte[]> clientData = new ConcurrentQueue<byte[]>()

prepareData メソッドでデータをエンキューし、sendData でデータを TryDequeue します

于 2013-10-10T20:55:03.533 に答える
0

また、問題が何であるかはわかりませんが、問題を解決する方法は次のとおりです。

この using ディレクティブを追加します

using System.Timers;

そして、クラスで prepareData と sendData-Method を使用してタイマーをフィールドとして追加します。

private Timer scheduler;

StartSending メソッドを追加します。

private void StartSending(byte[] clientData) {
    double interval = 2000; // 2000ms = 2s
    scheduler = new Timer(interval);
    scheduler.Elapsed += (sender, e) => {
        sendData("someIp", 123, clientData);
    };
    scheduler.Start();
}

clientData の準備ができたらすぐに、このメソッドを呼び出します。問題が解決しない場合は、問題を明確にしてください。

于 2013-10-10T20:29:47.077 に答える
0

既に述べたように、問題は clientData をローカル変数に格納していて、prepareData を終了すると単に破棄されることです。clientData は、クラス変数に格納するか、prepareData から返す必要があります。次のようにしてみてください。

private byte[] prepareData(string longFileName, string shortFileName)
{
    try
    {
        byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName);
        byte[] fileData = File.ReadAllBytes(longFileName);
        byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
        byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
        fileNameLen.CopyTo(clientData, 0);
        fileNameByte.CopyTo(clientData, 4);
        fileData.CopyTo(clientData, 4 + fileNameByte.Length);
        return clientData;
    }
    catch
    {
    }
}

private void sendData(string clientIP, int clientPort, byte[] clientData)
{
    TcpClient clientSocket = new TcpClient(clientIP, clientPort);
    NetworkStream networkStream = clientSocket.GetStream();
    networkStream.Write(clientData, 0, clientData.GetLength(0));
    networkStream.Close();
    clientSocket.Close();
}

このようにすれば、sendData メソッドの呼び出しにタイマーは必要ありません。次のように、prepareData が終了したら呼び出すだけです。

    var clientData = prepareData("longFileName", "shortFileName");
    sendData(clientData);

また

prepareData が本当に負荷の高いタスクである場合は、いくつかのスレッドを起動して 1 つのスレッドでファイル ブロックを読み取り、ConcurrentQueue (@dweeberly が提案) を使用してそれらを格納し、別のスレッドで sendData を呼び出す必要があります。

于 2013-10-10T21:17:17.263 に答える