【问题标题】:C# chaining methods using streams使用流的 C# 链接方法
【发布时间】:2018-12-04 21:51:40
【问题描述】:

我在 c# 中有两个不同的对象,它们使用流公开方法。

其中一个公开了一个将 Stream 作为参数并写入流的方法,而另一个公开了一个将 Stream 作为参数并从中读取的方法。

将内容写入 MemoryStream 是不可能的,因为有太多数据无法完全保存在内存中。有没有办法可以以某种方式链接这两种方法,还是我必须手动编写某种适配器才能在我自己之间插入?

编辑:

其中一个方法看起来像这样,它将对象序列化为流:

object1.WriteToStream(Stream s)

而另一个看起来像这样:

object2.Process(Stream input, Stream output)

第二种方法从输入流中读取,处理数据并将其写入另一个流。我的问题是我需要使用第二种方法来处理第一个对象的WriteToStream方法生成的数据。

【问题讨论】:

  • 请把您的代码发给我们好吗?
  • 请展示一些示例代码。
  • 为什么不创建一个结果对象?您可以向其中添加方法来处理其内部属性。您将受益于未来维护者的可扩展性和简单性
  • 除非您重写这两种方法以同时工作,否则您需要某种缓冲区。 MemoryStream 仍然是您的最佳选择。如果您唯一关心的不是将数据保存在内存中,那么您当然可以使用文件流。
  • MemoryStream 无法工作,因为数据过多(千兆字节)。并且将它写入中间文件对我来说也不起作用,因为完成处理的一部分是压缩并将其写入文件。拥有一个中间文件会使我的磁盘空间需求暂时增加一倍以上。

标签: c#


【解决方案1】:

是的,您可以“链接”这两种方法。 但有一些先决条件:

  • 输出流(写入流的参数)必须是全局的,或者可以从两个函数访问。
  • 这两个函数都运行在不同的线程上,以同步运行。使用Task.Run() 或不同的Thread
  • 要将此同步到线程,您可以使用Semaphore

这里是示例代码。但这不是工作代码,它只是一个骨架

using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        _pool = new Semaphore(0, 2);

        Thread threadWrite = new Thread(new ParameterizedThreadStart(WriterThread));
        Thread threadRead = new Thread(new ParameterizedThreadStart(ReadThread));

        threadWrite.Start(commonStream);
        threadRead.Start(commonStream);

        // Wait for half a second, to allow all the
        // threads to start and to block on the semaphore.
        Thread.Sleep(500);

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(3);

        Console.WriteLine("Main thread exits.");
    }

    private static void WriterThread(object objStream)
    {
        Stream stream = (Stream)objStream;
        while (true)
        {
            // lock the semaphore, because you want to write the stream
            _pool.WaitOne();

            // your code goes here, to write the stream to some data, but not all 

            //release the pool, to indicate to the other thread, there are data in stream 
            _pool.Release();


            if (IsAllDataWritten)
                break;
        }
    }

    private static void ReadThread(object objStream)
    {
        Stream stream = (Stream)objStream;
        while (true)
        {
            // lock the semaphore, because you want to write the stream
            _pool.WaitOne();

            // your code goes here, to read and process the stream data

            //release the pool, to indicate to the other thread, there are data in stream 
            _pool.Release();


            if (AllDataIsReaded )
                break;
        }
    }
} 

【讨论】:

    猜你喜欢
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2021-03-18
    • 1970-01-01
    相关资源
    最近更新 更多