Класс SomeTask может быть в двух состояниях:
— простаивает (можно изменять любые свойства, косяки с многопоточными обновлениями — проблемы вызывающего кода)
— работает (любые попытки изменить свойства/повторно запустить задачу, даже из другого потока — InvalidOperationException).
Чугуниевый прототип:
public class SomeTask
{
#region Fields
private readonly object lockKey = new object();
private volatile bool isBusy;
private string someOption;
#endregion
#region Public properties
public bool IsBusy
{
get
{
return isBusy;
}
}
public string SomeOption
{
get
{
return someOption;
}
set
{
ValidateNotBusy();
someOption = value;
}
}
#endregion
#region Core logic
private void ValidateNotBusy()
{
lock (lockKey)
{
if (isBusy)
{
throw new InvalidOperationException("blablabla");
}
}
}
public void Run()
{
bool run = false;
try
{
lock (lockKey)
{
if (!isBusy)
{
isBusy = true;
run = true;
}
}
if (run)
{
LongRunningMethod();
}
else
{
throw new InvalidOperationException("blablabla");
}
}
finally
{
if (run)
{
isBusy = false;
}
}
}
private void LongRunningMethod()
{
// ...
if (someOption.Length == 42)
{
// ...
}
// ...
}
#endregion
}
Как бы сделали вы?