我正在使用反射来遍历一个Type属性并将某些类型设置为默认值.现在,我可以对类型进行切换并default(Type)明确设置,但我宁愿在一行中进行.有默认的程序化等价物吗?
这有什么区别:
internal class MyClass
{
private readonly object _syncRoot = new Object();
public void DoSomething()
{
lock(_syncRoot)
{
...
}
}
public void DoSomethingElse()
{
lock(_syncRoot)
{
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
还有这个:
internal class MyClass
{
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomething()
{
...
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomethingElse()
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我看到的唯一区别是第一种方法锁定某个私有成员,而第二种方法锁定实例本身(因此它应该锁定实例中的其他所有内容).是否有任何使用方法的一般建议?我目前在项目中发现了两个具有相似目的的类,每个类都用不同的方法编写.
编辑:
也许还有一个问题.这是:
internal class MyClass
{
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomething()
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
完全相同:
internal class MyClass
{
public void DoSomething()
{
lock(this)
{
...
}
} …Run Code Online (Sandbox Code Playgroud) 假设我有一个需要使用InitializeAsync()方法执行异步初始化的类.我想确保初始化只执行一次.如果另一个线程在初始化正在进行时调用此方法,它将"等待"直到第一个调用返回.
我正在考虑以下的实现(使用SemaphoreSlim).有更好/更简单的方法吗?
public class MyService : IMyService
{
private readonly SemaphoreSlim mSemaphore = new SemaphoreSlim(1, 1);
private bool mIsInitialized;
public async Task InitializeAsync()
{
if (!mIsInitialized)
{
await mSemaphore.WaitAsync();
if (!mIsInitialized)
{
await DoStuffOnlyOnceAsync();
mIsInitialized = true;
}
mSemaphore.Release();
}
}
private Task DoStuffOnlyOnceAsync()
{
return Task.Run(() =>
{
Thread.Sleep(10000);
});
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
编辑:
由于我正在使用DI并且将注入此服务,因此将其作为"懒惰"资源使用或使用异步工厂对我来说不起作用(尽管在其他用例中它可能很好).因此,异步初始化应该封装在类中,并对IMyService消费者透明.
将初始化代码包装在"虚拟" AsyncLazy<>对象中的想法将完成这项工作,尽管对我来说感觉有点不自然.
是否System.Lazy<T>有无例外的缓存?或者懒惰的多线程初始化和缓存的另一个很好的解决方案?
我有以下程序(在这里小提琴):
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
namespace ConsoleApplication3
{
public class Program
{
public class LightsaberProvider
{
private static int _firstTime = 1;
public LightsaberProvider()
{
Console.WriteLine("LightsaberProvider ctor");
}
public string GetFor(string jedi)
{
Console.WriteLine("LightsaberProvider.GetFor jedi: {0}", jedi);
Thread.Sleep(TimeSpan.FromSeconds(1));
if (jedi == "2" && 1 == Interlocked.Exchange(ref _firstTime, 0))
{
throw new Exception("Dark side happened...");
}
Thread.Sleep(TimeSpan.FromSeconds(1));
return string.Format("Lightsaver for: {0}", jedi);
}
}
public class LightsabersCache
{
private readonly …Run Code Online (Sandbox Code Playgroud) 这可能就像在棍子上求月亮一样;但是是否有“C# 生产质量线程安全的内存中 LRU 缓存与到期?或者有没有人有最佳实践的想法来实现同样的事情?
(LRU 是“最近最少使用” - http://en.wikipedia.org/wiki/Cache_algorithms#LRU)
澄清一下:我想在具有以下接口的 ASP.Net MVC 站点中支持内存缓存:
public interface ICache
{
T GetOrAdd<T>(string key, Func<T> create, TimeSpan timeToLive) where T : class;
bool Remove(string key);
}
Run Code Online (Sandbox Code Playgroud)
Microsoft 的最佳解决方案似乎是“System.Runtime.Caching.MemoryCache”,但它似乎有几个警告:
代码如下所示:
public sealed class Cache : ICache
{
private readonly MemoryCache _cache;
public Cache()
{
_cache = MemoryCache.Default;
}
public T GetOrAdd<T>(string key, Func<T> create, TimeSpan timeToLive) where T : class
{
// This call kinda defeats …Run Code Online (Sandbox Code Playgroud) 对于不好的措辞和复杂的问题提前道歉,英语是我的第二语言.
我正在寻找一个数据结构来保存一个数组/列表/对象集合(在我的例子中 - 整数ID - 但这并不重要),它将跟踪元素的"使用频率".所以我可以运行后台作业并删除较少使用的元素(以释放内存使用).
类似的东西,当访问或搜索元素时- 元素被移动到"表面",将较少使用的元素"推到底部".同样,目标是确定"访问较少"的值并不时删除它们.
我正在考虑编写自己的类,继承/子类化一些现有的列表结构(LinkedList<T,T>或者Queue<T>可能),然后重载一些"GetElement"方法,以便它"返回元素并将其移动到列表的开头".所以稍后,在我的后台工作中,我可以从"列表末尾"中删除元素(b/c它们的访问频率较低).
谢谢!
更新:感谢您的评论.事实证明,"LRU"就是简单的英语.我正在关闭这个问题,因为谷歌搜索"LRU缓存c#"提供了大量的答案.
我试图在 .NET 缓存中保留内存中的条目列表,代表对我的应用程序的最后 N 个 HTTP 请求。为此使用的最佳 .NET 序列是什么?
List<T>、 not Dictionary<TKey,TValue>)。我可能会点击 URL /foo10 次,这不是唯一的,但所有内容都需要添加到序列中。我突然想到我可以使用 a Queue<T>,在排队时只需检查长度,如果达到容量,则将旧的出队。但担心线程安全(ConcurrentQueue<T>也许?)和最佳方法,因为这是我的应用程序的“热门”区域,需要优化。
谢谢!
c# ×7
.net ×5
algorithm ×1
asp.net-mvc ×1
async-await ×1
asynchronous ×1
caching ×1
collections ×1
default ×1
locking ×1
lru ×1
reflection ×1
sequences ×1