Ich teste einfache Caching-Logik in C#. Hier ist meine Cachemanager-Klasse:sollte ich lokale Variable in Multithreading sperren?
public class CacheManager
{
static List<string> _list = new List<string>();
static readonly object _syncobject = new object();
public static void ReloadList()
{
List<string> list = new List<string>();
Random r = new Random();
var count = r.Next(10);
for (int i = 0; i < count; i++)
{
list.Add("list" + i);
}
//lock (_syncobject)
{
_list = list;
}
}
public static IEnumerable<string> GetList()
{
//lock (_syncobject)
{
return _list;
}
}
}
Unten ist die Klasse, die viele Threads raubend Cachemanager laicht:
class Program
{
static void Main(string[] args)
{
//threads for re-loading the list
for (int i = 0; i < 3; i++)
{
Thread reloadThread = new Thread(ReloadList);
reloadThread.Start();
}
//threads for getting the list
for (int i = 0; i < 10; i++)
{
Thread tget = new Thread(PrintList);
tget.Start();
}
//threads for getting the list and storing in local variable then use it
for (int i = 0; i < 10; i++)
{
Thread tget = new Thread(PrintListWithLocalVariable);
tget.Start();
}
Console.ReadKey();
}
private static void ReloadList()
{
do
{
Console.WriteLine("Reloading **********");
CacheManager.ReloadList();
} while (true);
}
private static void PrintList()
{
do
{
foreach (var item in CacheManager.GetList())
{
if (item == null)
throw new Exception("i == null");
Console.WriteLine(item);
}
} while (true);
}
private static void PrintListWithLocalVariable()
{
do
{
var list = CacheManager.GetList();
foreach (var listitem in list)
{
var i = list.FirstOrDefault(x => x.Equals(listitem));
if (i == null)
throw new Exception("i == null");
Console.WriteLine("Printing with Local variable:" + listitem);
}
} while (true);
}
}
Mein Verständnis war, dass wir die _list Variable in Cachemanager sperren sollte, aber sieht nicht wie wir brauche das. Ich habe den obigen Test für eine Stunde oder so ausgeführt, aber habe keinen Fehler bekommen. Während ReloadThread die zufällige Anzahl von Listenelementen neu lädt, andere Threads, die die Liste durchlaufen, dachte ich, könnte Probleme haben. Kann mir jemand erklären, warum das Programm ohne Probleme läuft?
Danke.
Müssen Sie Ihren eigenen Cache erfinden? https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx. Versuchen Sie außerdem, eine ConcurrentCollection zu verwenden. https://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx –
FYI, '_list' ist keine" lokale "Variable. – crashmstr
Die Erklärung ist: weil du Glück hast. Sie können Glück haben, die nächsten 100 Male, die Sie dieses laufen lassen. Aber es wird dich umdrehen und an unbehaglichen Stellen beißen, sobald du es brauchst, um richtig zu arbeiten. – nvoigt