In duplex WCF service that works as parralel downloadmanager I have Downloader class that presents each download status and an ObservableCollection that contains Downloader instanses. When I try to serialize ObservableCollection via BinaryFormatter then I get SerializationException with message: "Type\System.Net.ConnectStream\ in assembly\System.Version 4.0.0.0, Culture=neutral, PublicKey Token=b77a5c561934e089\ is not marked as serializable". Below is condenced version of Downloader class:
[Serializable()]
public class Downloader
{
/// <summary>
/// "Download status changed" event.
/// </summary>
[field: NonSerialized()]
public event EventHandler<InServiceHandledDownloadStatusChangedEventArgs> InServiceHandledDownloadStatusChanged;
/// <summary>
/// URL of downloaded resource.
/// </summary>
private String _targetUrl;
/// <summary>
/// Path to save downloaded data on local drive.
/// </summary>
private String _pathToSave;
/// <summary>
/// The number of bytes downloaded from internet resource.
/// </summary>
private Int64 _downloadedBytesQuantity = 0;
/// <summary>
/// Current status of downloading ("Await", "Running", "Completed").
/// </summary>
private String _status = "Added";
/// <summary>
/// Task that performs download.
/// </summary>
[NonSerialized()]
public Task TaskPerformingDownload;
/// <summary>
/// The source of cancellation token for cancelling of TaskPerformingDownload.
/// </summary>
[NonSerialized()]
public CancellationTokenSource CancelDownloadTokenSource;
/// <summary>
/// Gets or sets stream to read downloaded data from internet.
/// </summary>
public Stream ReadСontentStream { get; set; }
/// <summary>
/// Gets or sets stream to write downloaded data to local drive.
/// </summary>
public Stream SaveСontentStream { get; set; }
/// <summary>
/// This method executes in TaskPerformingDownload and performs downloading.
/// of a resource from internet.
/// </summary>
/// <param name="p_CancellationToken">Cancellation Token</param>
public void PerformDownload(Object p_CancellationToken)
{
try
{
// Get cancellation token.
CancellationToken cancellationToken = (CancellationToken)p_CancellationToken;
// Check was the task canceled?
cancellationToken.ThrowIfCancellationRequested();
. . . . . . . .
HttpWebRequest webResourceRequest = (HttpWebRequest)WebRequest.Create(TargetUrl);
HttpWebResponse webResourceResponse = (HttpWebResponse)webResourceRequest.GetResponse();
this.ReadСontentStream = webResourceResponse.GetResponseStream();
this.SaveСontentStream = new FileStream(this.PathToSave, FileMode.Create, FileAccess.Write, FileShare.None);
int bytesReceivedInChank = 0;
byte[] downloadBuffer = new byte[2048];
// The downloading loop.
while ((bytesReceivedInChank = this.ReadСontentStream.Read(downloadBuffer, 0, downloadBuffer.Length)) > 0)
{
if (cancellationToken.IsCancellationRequested)
cancellationToken.ThrowIfCancellationRequested();
this.SaveСontentStream.Write(downloadBuffer, 0, bytesReceivedInChank);
. . . . . . . .
}
}
catch(Exception){. . . .}
finally
{
if (this.ReadСontentStream != null)
{
this.ReadСontentStream.Close();
this.ReadСontentStream.Dispose();
}
if (this.SaveСontentStream != null)
{
this.SaveСontentStream.Close();
this.SaveСontentStream.Dispose();
}
}
}
}
TaskPerformingDownload member is a TPL task performing one download. It is started from StartDownload() contract method which WCF service calls when client asks to do it. PerformDownload method is executed in this task. WCF service create as many Downloader instances as many downloads must be performed. One Downloader instance per each download. A SerializationException exception with message: "Type\System.Net.ConnectStream\ in assembly\System.Version 4.0.0.0, Culture=neutral, PublicKey Token=b77a5c561934e089\ is not marked as serializable" occurs only when I try to serialize ObservableCollection with completed downloads. When download is completed its task (TaskPerformingDownload member) has completed its work too and has no more executed. I try to dispose task in completed download but it doesn't help and SerializationException exception remains. But if there are only new downloads in the ObservableCollection so the downloads that havn't been run yet (so that the TaskPerformingDownload member of this download hasn't run yet) that in that case the ObservableCollection is serialized nice without any exceptions or errors. Can you give me any tip why this situation has place? It is very important for me.