Если решение Perl подходит для вас:
Пример файла:
$ cat file.sh
spool on to '$HOME/logfile.log';
login 'username' 'password';
Решение:
$ perl -pe 's/\$(\w+)/$ENV{$1}/g' file.sh
spool on to '/home/user/logfile.log';
login 'username' 'password';
Я думаю, что блокировка - это, по сути, единственный способ достичь этого самостоятельно, но платформа .NET должна быть в состоянии сделать это за вас, если вы используете блокирующий набор и параллельную очередь [ 112]. Коллекция Blocking дает вам реализацию модели «производитель / потребитель», которая является поточно-ориентированной.
Вот пример, который будет печатать числа по порядку.
class Program
{
private static BlockingCollection<Task> m_BlockingCollection = new BlockingCollection<Task>(new ConcurrentQueue<Task>());
private static int Counter;
static async Task Main(string[] args)
{
Task.Run(ProcessQueue); //Don't await for this demo!
Task.Run(AddStuffToQueue); //Don't await for this demo!
Console.ReadLine();
m_BlockingCollection.CompleteAdding();
while (!m_BlockingCollection.IsAddingCompleted)
Thread.Sleep(5);
}
private static void AddStuffToQueue()
{
while(true)
m_BlockingCollection.Add(new Task(() => Console.WriteLine(Interlocked.Increment(ref Counter))));
}
private static async Task ProcessQueue()
{
while (!m_BlockingCollection.IsCompleted && m_BlockingCollection.TryTake(out Task task))
ProcessTask(task);
}
private static void ProcessTask(Task task)
{
task.RunSynchronously();
}
}
Это может быть не идеальный пример, но я уверен, что вы поняли идею. Производитель / потребитель помещает параллельную очередь в очередь, поэтому задачи выполняются как «первый пришел / первый вышел» (FIFO).
Можно иметь несколько потребителей для блокирующего сбора, но если вы хотите, чтобы все обрабатывалось по одному, тогда достаточно одного потребителя, как продемонстрировано.
Надеюсь, это поможет!