Bien, simplemente no puedo entender bien los escenarios de subprocesos múltiples correctamente. Perdón por hacer una pregunta similar nuevamente, solo estoy viendo muchos "hechos" diferentes en Internet.¿Bloquea correctamente una lista <T> en escenarios MultiThreaded?
public static class MyClass {
private static List<string> _myList = new List<string>;
private static bool _record;
public static void StartRecording()
{
_myList.Clear();
_record = true;
}
public static IEnumerable<string> StopRecording()
{
_record = false;
// Return a Read-Only copy of the list data
var result = new List<string>(_myList).AsReadOnly();
_myList.Clear();
return result;
}
public static void DoSomething()
{
if(_record) _myList.Add("Test");
// More, but unrelated actions
}
}
La idea es que si se activa la grabación, llama a HacerAlgo() quedarán registradas en una lista interna, y regresó cuando StopRecording() es llamado.
Mi especificación es la siguiente:
- StartRecording no se considera seguro para subprocesos. El usuario debe llamar a esto mientras que ningún otro Thread llama a DoSomething(). Pero si de alguna manera podría ser, sería genial.
- StopRecording tampoco es oficialmente seguro para subprocesos. Una vez más, sería genial si pudiera ser, pero eso no es un requisito.
- HacerAlgo tiene que ser seguro para subprocesos
La forma más habitual parece ser:
public static void DoSomething()
{
object _lock = new object();
lock(_lock){
if(_record) _myList.Add("Test");
}
// More, but unrelated actions
}
Alternativamente, se declara una variable estática:
private static object _lock;
public static void DoSomething()
{
lock(_lock){
if(_record) _myList.Add("Test");
}
// More, but unrelated actions
}
Sin embargo, this answer dice que esta no impide que otros códigos accedan a él.
así que me pregunto
- ¿Cómo me cerraba bien una lista?
- ¿Debo crear el objeto de bloqueo en mi función o como una variable de clase estática?
- ¿Puedo ajustar la funcionalidad de inicio y detención de grabación también en un bloqueo de bloqueo?
- StopRecording() hace dos cosas: Establecer una variable booleana en falso (para evitar que DoSomething() agregue más cosas) y luego copiar la lista para devolver una copia de los datos al llamador). Supongo que _record = falso; es atómico y estará en efecto inmediatamente? Entonces, normalmente, no tendría que preocuparme por Multi-Threading aquí, a menos que algún otro Thread llame a StartRecording() nuevamente.
Al final del día, estoy buscando una forma de expresar "Está bien, esta lista es mía ahora, todos los otros hilos tienen que esperar hasta que haya terminado con eso".
si entiendo lo que necesita echar un vistazo, tuve el mismo problema https://stackoverflow.com/a/44414120/4745606 –