<ArrayOfBook xmlns="http://schemas.datacontract.org/2004/07/WcfService5" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Book><Abstract>Abstract_5000050</Abstract><Author>Author_5000050</Author><Comment>Comment_5000050</Comment><Content>Content_5000050</Content><ISBN>ISBN_5000050_92d5768b350d4d2e82616e3e233f42ee</ISBN><Id>5000050</Id><Name>Name_5000050</Name><Summary>Summary_5000050</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string><a:string>Tag_2</a:string><a:string>Tag_3</a:string><a:string>Tag_4</a:string><a:string>Tag_5</a:string></Tags><Title>Title_5000050</Title><Topic>Topic_5000050</Topic></Book><Book><Abstract>Abstract_5000051</Abstract><Author>Author_5000051</Author><Comment>Comment_5000051</Comment><Content>Content_5000051</Content><ISBN>ISBN_5000051_fd049961df5a402aa64227484a68946f</ISBN><Id>5000051</Id><Name>Name_5000051</Name><Summary>Summary_5000051</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string><a:string>Tag_2</a:string><a:string>Tag_3</a:string></Tags><Title>Title_5000051</Title><Topic>Topic_5000051</Topic></Book><Book><Abstract>Abstract_5000052</Abstract><Author>Author_5000052</Author><Comment>Comment_5000052</Comment><Content>Content_5000052</Content><ISBN>ISBN_5000052_72a7bb1c93f9472987ec215fc3139a02</ISBN><Id>5000052</Id><Name>Name_5000052</Name><Summary>Summary_5000052</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string><a:string>Tag_2</a:string><a:string>Tag_3</a:string></Tags><Title>Title_5000052</Title><Topic>Topic_5000052</Topic></Book><Book><Abstract>Abstract_5000053</Abstract><Author>Author_5000053</Author><Comment>Comment_5000053</Comment><Content>Content_5000053</Content><ISBN>ISBN_5000053_3d6694c01eea4e57b110965e1d2a634c</ISBN><Id>5000053</Id><Name>Name_5000053</Name><Summary>Summary_5000053</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string><a:string>Tag_2</a:string></Tags><Title>Title_5000053</Title><Topic>Topic_5000053</Topic></Book><Book><Abstract>Abstract_5000054</Abstract><Author>Author_5000054</Author><Comment>Comment_5000054</Comment><Content>Content_5000054</Content><ISBN>ISBN_5000054_c6b7d6f39b3f42af8a772960d5a85360</ISBN><Id>5000054</Id><Name>Name_5000054</Name><Summary>Summary_5000054</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string></Tags><Title>Title_5000054</Title><Topic>Topic_5000054</Topic></Book><Book><Abstract>Abstract_5000055</Abstract><Author>Author_5000055</Author><Comment>Comment_5000055</Comment><Content>Content_5000055</Content><ISBN>ISBN_5000055_62158a3eeac64fb3b03d86187e563ec8</ISBN><Id>5000055</Id><Name>Name_5000055</Name><Summary>Summary_5000055</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string></Tags><Title>Title_5000055</Title><Topic>Topic_5000055</Topic></Book><Book><Abstract>Abstract_5000056</Abstract><Author>Author_5000056</Author><Comment>Comment_5000056</Comment><Content>Content_5000056</Content><ISBN>ISBN_5000056_6e28c32d8aa248cb9e1c7383b9f0bf7a</ISBN><Id>5000056</Id><Name>Name_5000056</Name><Summary>Summary_5000056</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string></Tags><Title>Title_5000056</Title><Topic>Topic_5000056</Topic></Book><Book><Abstract>Abstract_5000057</Abstract><Author>Author_5000057</Author><Comment>Comment_5000057</Comment><Content>Content_5000057</Content><ISBN>ISBN_5000057_a2b828aa3535417e9594e992145fd212</ISBN><Id>5000057</Id><Name>Name_5000057</Name><Summary>Summary_5000057</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string><a:string>Tag_2</a:string><a:string>Tag_3</a:string><a:string>Tag_4</a:string></Tags><Title>Title_5000057</Title><Topic>Topic_5000057</Topic></Book><Book><Abstract>Abstract_5000058</Abstract><Author>Author_5000058</Author><Comment>Comment_5000058</Comment><Content>Content_5000058</Content><ISBN>ISBN_5000058_650d8cf2dba34bd3a61037d652243dd5</ISBN><Id>5000058</Id><Name>Name_5000058</Name><Summary>Summary_5000058</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string><a:string>Tag_2</a:string><a:string>Tag_3</a:string></Tags><Title>Title_5000058</Title><Topic>Topic_5000058</Topic></Book><Book><Abstract>Abstract_5000059</Abstract><Author>Author_5000059</Author><Comment>Comment_5000059</Comment><Content>Content_5000059</Content><ISBN>ISBN_5000059_746b87786a854839b2a32416a7e89590</ISBN><Id>5000059</Id><Name>Name_5000059</Name><Summary>Summary_5000059</Summary><Tags xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>Tag_0</a:string><a:string>Tag_1</a:string><a:string>Tag_2</a:string><a:string>Tag_3</a:string><a:string>Tag_4</a:string></Tags><Title>Title_5000059</Title><Topic>Topic_5000059</Topic></Book></ArrayOfBook>
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xmlStr)))
{
var serializer = new DataContractSerializer(
typeof(List<Book>),
rootName: "ArrayOfBook",
rootNamespace: "http://schemas.datacontract.org/2004/07/WcfService5"
);
var bookList = (List<Book>)serializer.ReadObject(ms);
Application.Current?.Dispatcher?.Invoke(() =>
{
BooksCollection = new ObservableCollection<Book>(bookList ?? new List<Book>());
MainTitle = $"{DateTime.Now},loaded {BooksCollection.Count} items," +
$"FirstId:{BooksCollection?.FirstOrDefault()?.Id}," +
$"LastId:{BooksCollection?.LastOrDefault()?.Id}";
});
}
![image]()
//WCF
//D:\C\WcfService5\WcfService5\IBookService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Text.Json;
namespace WcfService5
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IBookService" in both code and config file together.
[ServiceContract]
public interface IBookService
{
[OperationContract]
[WebGet(UriTemplate="/getbookslist?cnt={cnt}")]
List<Book> GetBooksList(int cnt);
}
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/WcfService5")]
public class Book : ICloneable
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string ISBN { get; set; }
[DataMember]
public string Abstract { get; set; }
[DataMember]
public string Author { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public string Content { get; set; }
[DataMember]
public string Summary { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public string Topic { get; set; }
[DataMember]
public List<string> Tags { get; set; }
public object Clone()
{
return DeepClone();
}
public Book DeepClone()
{
string jsonStr = System.Text.Json.JsonSerializer.Serialize(this);
Book bk = JsonSerializer.Deserialize<Book>(jsonStr);
return bk;
}
}
}
//D:\C\WcfService5\WcfService5\BookService.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading;
namespace WcfService5
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "BookService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select BookService.svc or BookService.svc.cs at the Solution Explorer and start debugging.
public class BookService : IBookService
{
private static long id = 0;
private Random rnd = new Random();
private (long, long) GetStartEnd(int cnt)
{
long end = Interlocked.Add(ref id, cnt);
long start = end - cnt;
return (start, end);
}
public List<Book> GetBooksList(int cnt)
{
List<Book> bksList=new List<Book>();
var (start,end) = GetStartEnd(cnt);
for(long i=start; i<end; i++)
{
var tags = new List<string>();
for(int j=0;j<rnd.Next(1,10);j++)
{
tags.Add($"Tag_{j}");
}
bksList.Add(new Book()
{
Id=i,
Name=$"Name_{i}",
Author=$"Author_{i}",
Abstract=$"Abstract_{i}",
Comment=$"Comment_{i}",
Content=$"Content_{i}",
ISBN=$"ISBN_{i}_{Guid.NewGuid():N}",
Summary=$"Summary_{i}",
Title=$"Title_{i}",
Topic=$"Topic_{i}",
Tags=tags
});
}
return bksList;
}
}
}
//D:\C\WcfService5\WcfService5\Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.8" />
<httpRuntime targetFramework="4.8"/>
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="BookServiceWebHttpBinding"
openTimeout="01:00:00"
closeTimeout="01:00:00"
sendTimeout="01:00:00"
receiveTimeout="01:00:00"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxDepth="2147483647"
maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647"/>
<security mode="None"/>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="BookServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="BookServiceEndPointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="WcfService5.BookService"
behaviorConfiguration="BookServiceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="WcfService5.IBookService"
behaviorConfiguration="BookServiceEndPointBehavior"
bindingConfiguration="BookServiceWebHttpBinding"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
//WPF
<Window x:Class="WpfApp12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp12"
mc:Ignorable="d"
Title="{Binding MainTitle}"
WindowState="Maximized">
<Window.DataContext>
<local:MainVM/>
</Window.DataContext>
<Grid>
<DataGrid ItemsSource="{Binding BooksCollection}"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.CacheLengthUnit="Item"
VirtualizingPanel.CacheLength="5,5"
ScrollViewer.CanContentScroll="True"
ScrollViewer.IsDeferredScrollingEnabled="True"
UseLayoutRounding="True"
SnapsToDevicePixels="True"
AutoGenerateColumns="True"
CanUserAddRows="True">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Setter Property="FontSize" Value="30"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontSize" Value="50"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>
</Window>
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks.Dataflow;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp12
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//DeepCloneDemo();
}
}
public class MainVM : INotifyPropertyChanged
{
private readonly HttpClient client = new HttpClient();
private string originalUrl = $"http://localhost:57987/BookService.svc/getbookslist?cnt=";
private bool isLoading = false;
public MainVM()
{
if(!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
_ = FetchDataFromWCFRelentless();
}
}
private async Task FetchDataFromWCFRelentless()
{
while(true)
{
await InitBooksCollectionAsync();
await Task.Delay(10000);
}
}
private async Task InitBooksCollectionAsync(int cnt=1000000)
{
if(isLoading)
{
return;
}
isLoading = true;
Application.Current?.Dispatcher?.InvokeAsync(() =>
{
MainTitle = $"{DateTime.Now},loading...";
},System.Windows.Threading.DispatcherPriority.Background);
string url = $"{originalUrl}{cnt}";
try
{
string xmlStr = await client.GetStringAsync(url);
if(string.IsNullOrWhiteSpace(xmlStr))
{
Application.Current?.Dispatcher.InvokeAsync(() =>
{
BooksCollection = new ObservableCollection<Book>();
},System.Windows.Threading.DispatcherPriority.Background);
}
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xmlStr)))
{
var serializer = new DataContractSerializer(
typeof(List<Book>),
rootName: "ArrayOfBook",
rootNamespace: "http://schemas.datacontract.org/2004/07/WcfService5"
);
var bookList = (List<Book>)serializer.ReadObject(ms);
Application.Current?.Dispatcher?.Invoke(() =>
{
BooksCollection = new ObservableCollection<Book>(bookList ?? new List<Book>());
MainTitle = $"{DateTime.Now},loaded {BooksCollection.Count} items," +
$"FirstId:{BooksCollection?.FirstOrDefault()?.Id}," +
$"LastId:{BooksCollection?.LastOrDefault()?.Id}";
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex?.Message);
}
finally
{
isLoading = false;
}
}
private string mainTitle = $"{DateTime.Now}";
public string MainTitle
{
get
{
return mainTitle;
}
set
{
if(value!=mainTitle)
{
mainTitle = value;
OnPropertyChanged();
}
}
}
private ObservableCollection<Book> booksCollection;
public ObservableCollection<Book> BooksCollection
{
get
{
return booksCollection;
}
set
{
if(value!=booksCollection)
{
booksCollection = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propName = "")
{
var handler = Volatile.Read(ref PropertyChanged);
if(handler==null)
{
return;
}
handler?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/WcfService5")]
public class Book : ICloneable
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string ISBN { get; set; }
[DataMember]
public string Abstract { get; set; }
[DataMember]
public string Author { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public string Content { get; set; }
[DataMember]
public string Summary { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public string Topic { get; set; }
[DataMember]
public List<string> Tags { get; set; }
public object Clone()
{
return DeepClone();
}
public Book DeepClone()
{
string jsonStr = System.Text.Json.JsonSerializer.Serialize(this);
Book bk = JsonSerializer.Deserialize<Book>(jsonStr);
return bk;
}
}
}
![image]()
![image]()
![image]()