.NET Асинхронное потоковое чтение-запись

Честно говоря, это кажется, что у Вас уже есть большинство оснований, охваченных.

+44 (0) 800 форматов, иногда (неправильно) используемых в Великобритании, являются раздражающими и не являются строго допустимыми согласно E.123, который является рекомендацией ITU-T для того, как должны быть отображены числа. Если у Вас нет копии E.123, он достойный внимания.

Если это имеет значение, сама телефонная сеть не всегда использует E.164. Часто будет флаг в ISDN передача сигналов сгенерированном PBX (или в сети, если Вы будете по паровому телефону), который говорит сеть, является ли набираемое число локальным, национальным или международным.

47
задан ROMANIA_engineer 3 November 2017 в 21:16
поделиться

2 ответа

Чтобы справиться с этим, вам нужно будет использовать обратный вызов из чтения NetStream. И, честно говоря, было бы проще поместить логику копирования в отдельный класс, чтобы вы могли поддерживать экземпляр активных потоков.

Я бы подошел к этому так (не тестировалось):

public class Assignment1
{
    public static void NetToFile(NetworkStream net, FileStream file) 
    {
        var copier = new AsyncStreamCopier(net, file);
        copier.Start();
    }

    public static void NetToFile_Option2(NetworkStream net, FileStream file) 
    {
        var completedEvent = new ManualResetEvent(false);

        // copy as usual but listen for completion
        var copier = new AsyncStreamCopier(net, file);
        copier.Completed += (s, e) => completedEvent.Set();
        copier.Start();

        completedEvent.WaitOne();
    }

    /// <summary>
    /// The Async Copier class reads the input Stream Async and writes Synchronously
    /// </summary>
    public class AsyncStreamCopier
    {
        public event EventHandler Completed;

        private readonly Stream input;
        private readonly Stream output;

        private byte[] buffer = new byte[4096];

        public AsyncStreamCopier(Stream input, Stream output)
        {
            this.input = input;
            this.output = output;
        }

        public void Start()
        {
            GetNextChunk();
        }

        private void GetNextChunk()
        {
            input.BeginRead(buffer, 0, buffer.Length, InputReadComplete, null);
        }

        private void InputReadComplete(IAsyncResult ar)
        {
            // input read asynchronously completed
            int bytesRead = input.EndRead(ar);

            if (bytesRead == 0)
            {
                RaiseCompleted();
                return;
            }

            // write synchronously
            output.Write(buffer, 0, bytesRead);

            // get next
            GetNextChunk();
        }

        private void RaiseCompleted()
        {
            if (Completed != null)
            {
                Completed(this, EventArgs.Empty);
            }
        }
    }
}
12
ответ дан 26 November 2019 в 19:32
поделиться

You're right, what you're doing is basically synchronous reading, because you use the WaitOne() method and it just stops the execution until the data is ready, that's basically the same as doing it using Read() instead of BeginRead() and EndRead().

What you have to do, is use the callback argument in the BeginRead() method, with it, you define a callback method (or a lambda expression), this method will be invoked when the information has been read (in the callback method you have to check for the end of the stream, and write to the output stream), this way you won't be blocking the main thread (you won't need the WaitOne() nor the EndRead().

Hope this helps.

0
ответ дан 26 November 2019 в 19:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: