2

I used this code to serialize an object

public void play(string url, string i)
    {
      MP3StreamingPanel mp3=new MP3StreamingPanel ( );
      mp3.play ( url );
      HttpContext . Current . Session [ i ] = mp3;

then when i want to get it, some value in the mp3 attribute still 'null'

  MP3StreamingPanel mp3=new MP3StreamingPanel ( );
  mp3 = HttpContext . Current . Session [ i ] as MP3StreamingPanel;

and this is the MP3StreamingPanel class

    [Serializable]
    public class MP3StreamingPanel 
        {

        enum StreamingPlaybackState
            {
            Stopped ,
            Playing ,
            Buffering ,
            Paused
            }




[NonSerialized]
public HttpWebRequest webRequest;
[NonSerialized]
public System.Timers.Timer timer1 = new System . Timers . Timer ( );
public SerializableVolumeWaveProvider16 volumeProvider;
delegate void ShowErrorDelegate ( string message );
public string gurl="";
public SerializableBufferedWaveProvider bufferedWaveProvider;
public SerializableWaveOut waveOut;
private  volatile StreamingPlaybackState playbackState;
public volatile bool fullyDownloaded;

public MP3StreamingPanel ( )
    {
    }

public void InitTimer ( )
    {
    timer1 . Elapsed += new ElapsedEventHandler ( timer1_Tick );
    timer1 . Interval = 250; // in miliseconds
    timer1 . Start ( );
    }
public void timer1_Tick ( object sender , ElapsedEventArgs e )
    {
    if ( playbackState != StreamingPlaybackState . Stopped )
        {
        if ( this . waveOut == null && this . bufferedWaveProvider != null )
            {
            Debug . WriteLine ( "Creating WaveOut Device" );
            this . waveOut = CreateWaveOut ( );
            waveOut . PlaybackStopped += waveOut_PlaybackStopped;
            this . volumeProvider = new SerializableVolumeWaveProvider16 ( `enter code here`bufferedWaveProvider );
            waveOut . Init ( volumeProvider );

            }
        else if ( bufferedWaveProvider != null )
            {
            var bufferedSeconds = bufferedWaveProvider . BufferedDuration . TotalSeconds;

            if ( bufferedSeconds < 0.5 && this . playbackState == StreamingPlaybackState . Playing && !this . fullyDownloaded )
                {
                this . playbackState = StreamingPlaybackState . Buffering;
                waveOut . Pause ( );
                Debug . WriteLine ( String . Format ( "Paused to buffer, waveOut.PlaybackState={0}" , waveOut . PlaybackState ) );
                }
            else if ( bufferedSeconds > 4 && this . playbackState == StreamingPlaybackState . Buffering )
                {
                waveOut . Play ( );
                Debug . WriteLine ( String . Format ( "Started playing, waveOut.PlaybackState={0}" , waveOut . PlaybackState ) );
                this . playbackState = StreamingPlaybackState . Playing;
                }
            else if ( this . fullyDownloaded && bufferedSeconds == 0 )
                {
                Debug . WriteLine ( "Reached end of stream" );
                stop ( );
                }
            }

        }
    }


public void StreamMP3 ( object state )
    {
    this . fullyDownloaded = false;
    string url = ( string ) state;
    webRequest = ( HttpWebRequest ) WebRequest . Create ( url );
    HttpWebResponse resp = null;
    try
        {
        resp = ( HttpWebResponse ) webRequest . GetResponse ( );
        }
    catch ( WebException e )
        {
        if ( e . Status != WebExceptionStatus . RequestCanceled )
            {
            Console.WriteLine ( e . Message );
            }
        return;
        }
    byte[] buffer = new byte [ 16384 * 4 ]; 

    IMp3FrameDecompressor decompressor = null;
    try
        {
        using ( var responseStream = resp . GetResponseStream ( ) )
            {
            var readFullyStream = new ReadFullyStream ( responseStream );
            do
                {
                if ( bufferedWaveProvider != null && bufferedWaveProvider . BufferLength - bufferedWaveProvider . BufferedBytes < bufferedWaveProvider . WaveFormat . AverageBytesPerSecond / 4 )
                    {
                    Debug . WriteLine ( "Buffer getting full, taking a break" );
                    Thread . Sleep ( 500 );
                    }
                else
                    {
                    Mp3Frame frame = null;
                    try
                        {
                        frame = Mp3Frame . LoadFromStream ( readFullyStream );
                        }
                    catch ( EndOfStreamException )
                        {
                        this . fullyDownloaded = true;

                        break;
                        }
                    catch ( WebException )
                        {

                        break;
                        }
                    if ( decompressor == null )
                        {
                        WaveFormat waveFormat = new Mp3WaveFormat ( frame . SampleRate , frame . ChannelMode == ChannelMode . Mono ? 1 : 2 , frame . FrameLength , frame . BitRate );
                        decompressor = new AcmMp3FrameDecompressor ( waveFormat );
                        this . bufferedWaveProvider = new SerializableBufferedWaveProvider ( decompressor . OutputFormat );
                        this . bufferedWaveProvider . BufferDuration = TimeSpan . FromSeconds ( 20 ); // allow us to get well ahead of ourselves
                        }
                    int decompressed = decompressor . DecompressFrame ( frame , buffer , 0 );
                     bufferedWaveProvider . AddSamples ( buffer , 0 , decompressed );
                    }

                } while ( playbackState != StreamingPlaybackState . Stopped );
            Debug . WriteLine ( "Exiting" );
            decompressor . Dispose ( );
            }
        }
    finally
        {
        if ( decompressor != null )
            {
            decompressor . Dispose ( );
            }
        }
    }

public void play ( string url )
    {
    if ( playbackState == StreamingPlaybackState . Stopped )
        {
            playbackState = StreamingPlaybackState . Buffering;
            this . bufferedWaveProvider = null;
            ThreadPool . QueueUserWorkItem ( new WaitCallback ( StreamMP3 ) , url );
            gurl = url;
            InitTimer ( );
            timer1 . Enabled = true;
        }
    else if ( playbackState == StreamingPlaybackState . Paused )
        {
             playbackState = StreamingPlaybackState . Buffering;
        }
    }

public void stop ( )
    {

    if ( playbackState != StreamingPlaybackState . Stopped )
        {
        if ( !fullyDownloaded )
            {
            webRequest . Abort ( );
            }
        this . playbackState = StreamingPlaybackState . Stopped;
        if ( waveOut != null )
            {
            waveOut . Stop ( );
            waveOut . Dispose ( );
            waveOut = null;
            }
        timer1 . Enabled = false;
        // n.b. streaming thread may not yet have exited
        Thread . Sleep ( 500 );
         }
    }



public SerializableWaveOut CreateWaveOut ( )
    {
    return new SerializableWaveOut ( );

    }


public void pause ( )
    {
    if ( playbackState == StreamingPlaybackState . Playing || playbackState == StreamingPlaybackState . Buffering )
        {
        waveOut . Pause ( );
        Debug . WriteLine ( String . Format ( "User requested Pause, waveOut.PlaybackState={0}" , waveOut . PlaybackState ) );
        playbackState = StreamingPlaybackState . Paused;
        }
    }

public void buttonStop_Click ( object sender , EventArgs e )
    {
    stop ( );
    }

private void waveOut_PlaybackStopped ( object sender , StoppedEventArgs e )
    {
    Debug . WriteLine ( "Playback Stopped" );
    if ( e . Exception != null )
        {
        MessageBox . Show ( String . Format ( "Playback Error {0}" , e . Exception . Message ) );
        }
    }
}

for SerializableVolumeWaveProvider16 , SerializableBufferedWaveProviderand SerializableWaveOut are classes that I declared as [Serializable] but i can't get there values after serialization

4

1 に答える 1

2

複雑なオブジェクトをセッション / キャッシュに保存しない

ここでセッションに保存しているオブジェクトは複雑で、多くの可動部分があります。キャッシュとセッションを使用するときに人々が犯す主な間違いは、「アクティブな」オブジェクトを保存することです (タイマー、Web リクエストなどがあります)。(セッション、キャッシュ、またはファイルシステムなどに)コールドハード非アクティブデータのみを保存する必要があります。データのみを含む別の DTO レイヤーを作成することを強くお勧めします。例えば:

public class Something {
    public string Name {get;set;}
    public int SomeNumber {get;set;}
    public byte[] Blob {get;set;}
    // ... more simple data values
}

この形式の何かを格納/取得するのが理想的です。シンプルで理解しやすいなど。次に、必要に応じて、この DTO モデルと実際のモデルとの間でマッピングします。

実際には、DTO を不変にするのがさらに良い考えです。これにより、プロバイダーが実際にはシリアル化せず、メモリ内に保持する場合の複雑さを回避できます。それ以外の場合、以下はあいまいです。

var obj = session[key] as Something;
if(obj != null) {
    obj.Name = "new name";
}

シリアライズプロバイダーでは、最後に明示的に再度保存しない限り、通常、その変更は反映されません。メモリ内プロバイダーを使用すると、他のすべての呼び出し元にすぐに表示されます (ユーザーは複数の同時要求を持つことができることに注意してください)。

session/cache/etc を使用しているときに DTO ベースのモデルに移行すると、理解しやすく、明らかに正しいコードを書かなければならなくなります。「誰も推測できない理由で働くことがある」ではなく。

于 2013-03-28T13:02:38.980 に答える