背景 日常開發中,經常需要對一些響應不是很快的關鍵業務介面增加防重功能,即短時間內收到的多個相同的請求,只處理一個,其餘不處理,避免產生臟數據。這和冪等性(idempotency)稍微有點區別,冪等性要求的是對重覆請求有相同的效果和結果,通常需要在介面內部執行業務操作前檢查狀態;而防重可以認為是一個 ...
今天有一個場景需要用到對象的複製,寫個深度拷貝的代碼,做個記錄
在同一個業務中包含多處回調的場景下:有一個對象是處理業務邏輯的回調中使用,但是在其他回調函數中會清理這個對象;
出現了一個問題在處理業務邏輯的回調函數中,還沒有使用完,其他回調函數清空了這個對象,所有代碼中儘量不要用鎖,所以不考慮用鎖的情況
考慮到主要業務處理回調邏輯比較獨立;所以想到了2種方案,
- 線程內部對象
- 深度拷貝
因為業務處理回調函數執行時間很短,又沒有等待邏輯,所以不合適使用線程池+線程內部對象的方式處理,所以在處理業務邏輯函數入口使用了對象的深度拷貝,保證了函數內部都使用的深度拷貝的對象;
深度拷貝的示例代碼如下,留作備用:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace DeepCopyExample
{
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
public Person(string name, int age, Address address)
{
Name = name;
Age = age;
Address = address;
}
public Person DeepCopy()
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Position = 0;
return (Person)formatter.Deserialize(stream);
}
}
}
[Serializable]
public class Address
{
public string City { get; set; }
public string Country { get; set; }
public Address(string city, string country)
{
City = city;
Country = country;
}
}
internal class Program
{
static void Main(string[] args)
{
Address address = new Address("Beijing", "China");
Person person1 = new Person("duwenlong ", 31, address);
Person person2 = person1.DeepCopy();
Console.WriteLine($"Person1 Name: {person1.Name}, Age: {person1.Age}, City: {person1.Address.City}, Country: {person1.Address.Country}");
Console.WriteLine($"Person2 Name: {person2.Name}, Age: {person2.Age}, City: {person2.Address.City}, Country: {person2.Address.Country}");
Console.WriteLine("changed Person2 City to Henan");
person2.Address.City = "Henan";
Console.WriteLine($"Person1 Name: {person1.Name}, Age: {person1.Age}, City: {person1.Address.City}, Country: {person1.Address.Country}");
Console.WriteLine($"Person2 Name: {person2.Name}, Age: {person2.Age}, City: {person2.Address.City}, Country: {person2.Address.Country}");
Console.ReadKey();
}
}
}
觀察輸出Persion2的城市修改了,Persion1的沒有變化;