一些在程序初始化時交給后臺線程異步賦值的屬性,完成set之前有可能UI就準備好了,也就是用戶可以操作了,操作中如果需要get某個尚未set的屬性,我希望代碼阻塞,直到set后繼續(xù)執(zhí)行,當然如果get之前就已經set好了就無阻塞了。所以這種阻塞最多只用一次,為此專門弄個鎖或者信號對象我覺得不地道,這種場景應該很典型,我想知道有沒有比較優(yōu)雅的方式(比如在這種屬性上加個[xxx]特性之類)寫這種屬性?
使用同步事件即可:
private ManualResetEvent _lockEvent = new ManualResetEvent(false);
private string prop;
public string Prop {
get {
_lockEvent.WaitOne();
return prop;
}
set {
prop = value;
_lockEvent.Set();
}
}
類似這樣?但是沒有可以直接使用的Attribute,不過可以自己實現(xiàn)一套
using System;
using System.Threading.Tasks;
namespace Test6
{
class Program
{
static void Main(string[] args)
{
var t = new Test();
Console.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + t.NormalProperty);
//Console.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + t.LazyProperty);
Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] pretending doing something that will takes 3s");
System.Threading.Thread.Sleep(3000);
Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] something is done in 3s");
var lazyValue = t.LazyProperty;
Console.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + lazyValue);
Console.ReadLine();
}
}
public class Test
{
public string NormalProperty { get; set; }
public string LazyProperty
{
get
{
//if (GetLazyPropertyValue.IsCompleted)
//{
return GetLazyPropertyValue.Result;
//}
//else
//{
// return "LazyProperty uninitialized";
//}
}
}
public Test()
{
this.NormalProperty = "NormalProperty";
GetLazyPropertyValue.Start();
}
protected Task<string> GetLazyPropertyValue = new Task<string>(() =>
{
System.Threading.Thread.Sleep(5000);
return "LazyProperty initialized";
});
}
}
升了個級,加上了Attribute
using System;
using System.Dynamic;
using System.Reflection;
using System.Threading.Tasks;
namespace Test6
{
class Program
{
static void Main(string[] args)
{
dynamic t = new DynamicProxy(new Test());
Console.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + t.NormalProperty);
Console.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + t.LazyPropertyWithDefaultValue);
Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] pretending doing something that will takes 3s");
System.Threading.Thread.Sleep(3000);
Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] something is done in 3s");
var lazyValue = t.LazyProperty;
Console.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + lazyValue);
Console.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + t.LazyPropertyWithDefaultValue);
Console.ReadLine();
}
}
[LazyPropertyIncluded]
public class Test
{
public string NormalProperty { get; set; }
[LazyProperty(InitializerName = "InitLazyProperty")]
public string LazyProperty { get; }
[LazyProperty(HasDefaultValue =true, Defaultalue = "LazyPropertyWithDefaultValue Default Value")]
public string LazyPropertyWithDefaultValue { get; }
protected Task<string> InitLazyProperty = new Task<string>(() =>
{
Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] start initializing LazyProperty");
System.Threading.Thread.Sleep(5000);
return "LazyProperty initialized";
});
protected Task<string> InitLazyPropertyWithDefaultValue = new Task<string>(() =>
{
Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] start initializing LazyPropertyWithDefaultValue");
System.Threading.Thread.Sleep(5000);
return "LazyPropertyWithDefaultValue initialized";
});
public Test()
{
this.NormalProperty = "NormalProperty";
}
}
[AttributeUsage(AttributeTargets.Property)]
public class LazyPropertyAttribute : Attribute
{
public string InitializerName { get; set; }
public bool HasDefaultValue { get; set; }
public object Defaultalue { get; set; }
}
[AttributeUsage(AttributeTargets.Class)]
public class LazyPropertyIncludedAttribute : Attribute { }
public class DynamicProxy : DynamicObject
{
readonly object[] _sources;
public DynamicProxy(params object[] sources)
{
this._sources = sources;
// run init method for lazy properties
foreach (var src in this._sources)
{
var attr = src.GetType().GetCustomAttribute<LazyPropertyIncludedAttribute>();
if (attr != null)
{
foreach (var prop in src.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
var propAttr = prop.GetCustomAttribute<LazyPropertyAttribute>();
if (propAttr != null)
{
var initTask = propAttr.InitializerName ?? "Init" + prop.Name;
var task = src.GetType().GetField(initTask, BindingFlags.Instance | BindingFlags.NonPublic);
if (task != null)
{
((Task)task.GetValue(src)).Start();
}
else
{
throw new MethodAccessException("Cannot find initialization method [" + initTask + "] for lazy prop: " + prop.Name);
}
}
}
}
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
object propValue = null;
foreach (var src in this._sources)
{
var prop = src.GetType().GetProperty(binder.Name);
if (prop != null)
{
var propAttr = prop.GetCustomAttribute<LazyPropertyAttribute>();
if (propAttr == null)
{
propValue = prop.GetValue(src);
}
else
{
var initTask = propAttr.InitializerName ?? "Init" + prop.Name;
var task = src.GetType().GetField(initTask, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(src) as Task;
if (!task.IsCompleted && propAttr.HasDefaultValue)
{
propValue = propAttr.Defaultalue;
}
else
{
Task.WaitAll(task);
propValue = Convert.ChangeType(task.GetType().GetProperty("Result").GetValue(task), prop.PropertyType);
}
}
break;
}
}
if (propValue == null)
{
propValue = binder.Name + " from dynamic proxy";
}
result = propValue;
return true;
}
}
}
北大青鳥APTECH成立于1999年。依托北京大學優(yōu)質雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學院和江蘇省首批服務外包人才培訓基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團創(chuàng)建于1999年,經過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術與教育服務機構,發(fā)展為教育服務業(yè)的綜合性企業(yè)集團,成為集合面授教學培訓、網(wǎng)
達內教育集團成立于2002年,是一家由留學海歸創(chuàng)辦的高端職業(yè)教育培訓機構,是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔任項目經理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責任公司從事總經理職務負責iOS教學及管理工作。
浪潮集團項目經理。精通Java與.NET 技術, 熟練的跨平臺面向對象開發(fā)經驗,技術功底深厚。 授課風格 授課風格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應用開發(fā)經驗。曾經歷任德國Software AG 技術顧問,美國Dachieve 系統(tǒng)架構師,美國AngelEngineers Inc. 系統(tǒng)架構師。