Skip to content

Commit

Permalink
v1.1 增加 TryGet 方法当未注册时返回 null
Browse files Browse the repository at this point in the history
  • Loading branch information
28810 authored and 28810 committed Mar 29, 2020
1 parent 65c3143 commit ab7118c
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 35 deletions.
2 changes: 1 addition & 1 deletion ConsoleApp1/ConsoleApp1.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="IdleBus" Version="1.0.10" />
<ProjectReference Include="..\IdleBus\IdleBus.csproj" />
</ItemGroup>

</Project>
61 changes: 42 additions & 19 deletions ConsoleApp1/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,66 @@ class Program
{
class WangTask : IDisposable
{
public string Name { get; private set; }
public WangTask(string name)
static Lazy<IdleBus> _ibLazy = new Lazy<IdleBus>(() =>
{
this.Name = name;
var ib = new IdleBus();
ib.Notice += new EventHandler<IdleBus<IDisposable>.NoticeEventArgs>((s, e) =>
{
});
return ib;
});
static IdleBus Ib => _ibLazy.Value;

public string Key { get; private set; }
public TimeSpan Timeout { get; private set; }
public Action Handle { get; private set; }

private WangTask() { } //不允许 new WangTask()

public static void Register(string key, TimeSpan timeout, Action handle)
{
var task = new WangTask
{
Key = key,
Timeout = timeout,
Handle = handle
};
Ib.Register(key, () => task, timeout);
Ib.Get(key);
}
public static void Remove(string key)
{
Ib.TryRemove(key);
}

public void Dispose()
{
//todo 到期执行
Ib.TryRemove(this.Key);

Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {this.Name} 被执行");
try
{
this.Handle?.Invoke();
}
catch (Exception ex)
{
Register(this.Key, this.Timeout, this.Handle); //出错了,重新放入调度
}
}
}

static void Main(string[] args)
{
var ib = new IdleBus(TimeSpan.FromSeconds(10));
ib.Notice += (_, e2) =>
{
if (e2.NoticeType == IdleBus<IDisposable>.NoticeType.AutoCreate ||
e2.NoticeType == IdleBus<IDisposable>.NoticeType.AutoRelease)
{
//var log = $"[{DateTime.Now.ToString("HH:mm:ss")}] 线程{Thread.CurrentThread.ManagedThreadId}:{e2.Log}";
//Trace.WriteLine(log);
//Console.WriteLine(log);
}
};

Enumerable.Range(0, 10000).ToList().ForEach(idx =>
{
var key = "wang_" + idx;
ib.TryRegister(key, () => new WangTask(key), TimeSpan.FromSeconds(30));
ib.Get(key);//开始计时
WangTask.Register(key, TimeSpan.FromSeconds(30), () =>
{
Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {key} 被执行");
});
});

Console.ReadKey();
ib.Dispose();
}
}
}
4 changes: 2 additions & 2 deletions IdleBus/IdleBus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net40</TargetFrameworks>
<Version>1.0.10</Version>
<Version>1.1.0</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>IdleBus 空闲对象管理容器,有效组织对象重复利用,自动创建、销毁,解决【实例】过多且长时间占用的问题。</Description>
Expand All @@ -16,7 +16,7 @@
<IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>YeXiangQin.pfx</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>yxq.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
</PropertyGroup>

Expand Down
19 changes: 14 additions & 5 deletions IdleBus/IdleBus.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion IdleBus/IdleBus`1.ThreadScan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;

Expand Down Expand Up @@ -42,7 +43,7 @@ void ThreadScanWatchHandler()
}
couter = 0;

var keys = _dic.Keys;
var keys = _dic.Keys.ToArray();
long keysIndex = 0;
foreach (var key in keys)
{
Expand Down
26 changes: 20 additions & 6 deletions IdleBus/IdleBus`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,32 @@ public IdleBus(TimeSpan idle)
}

/// <summary>
/// 根据 key 获得或创建【实例】(线程安全)
/// 根据 key 获得或创建【实例】(线程安全)<para></para>
/// key 未注册时,抛出异常
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public T Get(string key)
public T Get(string key) => InternalGet(key, true);
/// <summary>
/// 根据 key 获得或创建【实例】(线程安全)<para></para>
/// key 未注册时,返回 null
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public T TryGet(string key) => InternalGet(key, false);

T InternalGet(string key, bool isThrow)
{
if (isdisposed) throw new Exception($"{key} 实例获取失败 ,{nameof(IdleBus<T>)} 对象已释放");
if (isdisposed && isThrow) throw new Exception($"{key} 实例获取失败 ,{nameof(IdleBus<T>)} 对象已释放");
if (_dic.TryGetValue(key, out var item) == false)
{
var error = new Exception($"{key} 实例获取失败,因为没有注册");
this.OnNotice(new NoticeEventArgs(NoticeType.Get, key, error, error.Message));
throw error;
if (isThrow)
{
var error = new Exception($"{key} 实例获取失败,因为没有注册");
this.OnNotice(new NoticeEventArgs(NoticeType.Get, key, error, error.Message));
throw error;
}
return null;
}

var now = DateTime.Now;
Expand Down
Binary file added IdleBus/yxq.snk
Binary file not shown.
4 changes: 4 additions & 0 deletions TestCore31/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ static void Main(string[] args)
}
};

var testkey1 = ib.TryGet("key1");

ib
.Register("key1", () => new ManualResetEvent(false))
.Register("key2", () => new AutoResetEvent(false));

var testkey2 = ib.TryGet("key1");

for (var a = 3; a < 2000; a++)
ib.Register("key" + a, () => new System.Data.SqlClient.SqlConnection());

Expand Down
12 changes: 11 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,22 @@ new IdleBus\<T\> 可【自定义类型】注入,如: new IdleBus\<IFreeSql\>
| void Ctor(TimeSpan idle) | 指定空闲时间,创建空闲容器 |
| IdleBus Register(string key, Func\<T\> create) | 注册(其类型必须实现 IDisposable) |
| IdleBus Register(string key, Func\<T\> create, TimeSpan idle) | 注册,单独设置空间时间 |
| T Get(string key) | 获取【实例】(线程安全) |
| T Get(string key) | 获取【实例】(线程安全),key 未注册时,抛出异常 |
| T TryGet(string key) | 获取【实例】(线程安全),key 未注册时,返回 null |
| void Remove(string key) | 删除已注册的 |
| int UsageQuantity | 已创建【实例】数量 |
| int Quantity | 注册数量 |
| event Notice | 容器内部的变化通知,如:自动释放、自动创建 |

> 注意:Register 参数 create 属于对象创建器,切莫直接返回外部创建好的对象,下面是错误的做法:
```csharp
var obj = new Xxx();
ib.Register("key01", () => obj); //错了,错了,错了
ib.Register("key01", () => new Xxx()); //正确
```

## 设计思路

IdleBus 和对象池不同,对象池是队列设计,我们是 KV 设计。
Expand Down

0 comments on commit ab7118c

Please sign in to comment.