我使用此代码序列化对象
public void play(string url, string i)
{
MP3StreamingPanel mp3=new MP3StreamingPanel ( );
mp3.play ( url );
HttpContext . Current . Session [ i ] = mp3;
然后当我想得到它时,mp3属性中的某些值仍然是' null'
MP3StreamingPanel mp3=new MP3StreamingPanel ( );
mp3 = HttpContext . Current . Session [ i ] as MP3StreamingPanel;
这是MP3StreamingPanel类
[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 ) );
}
}
}
SerializableVolumeWaveProvider16
的,SerializableBufferedWaveProvider
和SerializableWaveOut
是我声明为[Serializable]的类
但序列化后我无法获得价值
答案 0 :(得分:2)
您在会话中存储的对象很复杂,并且有许多移动部件。人们在使用缓存和会话时犯的主要错误是存储“活动”对象(哎呀,它有一个计时器,一个Web请求等)。您应该只存储(在会话,缓存或文件系统等)冷硬非活动数据。我强烈建议你创建一个单独的DTO层,它只包含 data ;例如:
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";
}
使用序列化提供程序,除非在最后再次明确存储,否则通常不会反映该更改;使用内存中提供程序,所有其他调用方都可以立即看到它(请记住,用户可以有多个并发请求)。
如果在使用会话/缓存/等时转移到基于DTO的模型,您将强制编写可理解且明显正确的代码。而不是“有时因无人能猜的原因而工作”。