gpt4 book ai didi

c# - 序列化异常 : "Type\...\in assembly\...\is not marked as serializable" appears when I try to serialize ObservableCollection

转载 作者:太空宇宙 更新时间:2023-11-03 21:30:25 32 4
gpt4 key购买 nike

在用作并行下载管理器的双工 WCF 服务中,我有一个显示每个下载状态的下载器类和一个包含下载器实例的 ObservableCollection。当我尝试通过 BinaryFormatter 序列化 ObservableCollection 时,我得到 SerializationException 消息:“Type\System.Net.ConnectStream\in assembly\System.Version 4.0.0.0, Culture=neutral, PublicKey Token=b77a5c561934e089\is not marked as serializable”。下面是 Downloader 类的精简版:

[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 成员是执行一次下载的 TPL 任务。它是从 StartDownload() 契约(Contract)方法开始的,当客户端要求这样做时,WCF 服务会调用该方法。在此任务中执行 PerformDownload 方法。 WCF 服务创建与必须执行的下载一样多的下载器实例。每次下载一个下载器实例。带有消息的 SerializationException 异常:“Type\System.Net.ConnectStream\in assembly\System.Version 4.0.0.0, Culture=neutral, PublicKey Token=b77a5c561934e089\is not marked as serializable”仅当我尝试序列化 ObservableCollection 时才会发生下载。下载完成后,其任务(TaskPerformingDownload 成员)也已完成其工作,不再执行。我尝试在已完成的下载中处理任务,但它没有帮助并且 SerializationException 异常仍然存在。但是,如果 ObservableCollection 中只有新的下载,那么尚未运行的下载(因此此下载的 TaskPerformingDownload 成员尚未运行),在这种情况下,ObservableCollection 序列化很好,没有任何异常或错误。你能告诉我为什么会出现这种情况吗?这对我来说非常重要。

最佳答案

您正在尝试序列化一个Stream。这是灾难的根源:流不是数据桶——它们是管道;它们很少以任何有意义的方式序列化,如果有的话。我的建议很简单:不要那样做。事实上,根本不要尝试序列化 Downloader ;您应该序列化数据,而不是实现状态。创建一个单独的模型,仅用于序列化,其中包含您要以最简单、最明显的方式存储的数据。如果你想序列化一个二进制请求/响应:byte[]。等等。

另外:出于多种原因,我强烈建议不要在几乎所有场景中使用 BinaryFormatter

关于c# - 序列化异常 : "Type\...\in assembly\...\is not marked as serializable" appears when I try to serialize ObservableCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24573122/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com