почему локальная переменная не может быть энергозависима в C#?

for k,v in kwarg.iteritems():
   setattr(self, k, v)

В котором setattr(self, "bin", "val") похоже на вызов self.bin = "val"

Однако более желательно иметь белый список, как у @Sven Marnach.

17
задан Patrick Huizinga 23 June 2009 в 12:07
поделиться

3 ответа

Существует примитив потоковой передачи, ManualResetEvent , который выполняет именно эту задачу - вы не хотите использовать логический флаг.

Что-то вроде этого должно выполнять job:

public void MyTest()
{
    var doneEvent = new ManualResetEvent(false);

    myEventRaiser.OnEvent += delegate { doStuff(); doneEvent.Set(); };
    myEventRaiser.RaiseEventInSeparateThread();
    doneEvent.WaitOne();

    Assert.That(stuff);
}

Что касается отсутствия поддержки ключевого слова volatile в локальных переменных, я не думаю, что есть какая-либо причина, по которой это может быть теоретически невозможным в C #. Скорее всего, он не поддерживается просто потому, что до C # 2.0 такая функция не использовалась. Теперь, когда существуют анонимные методы и лямбда-функции, такая поддержка потенциально может стать полезной. Кто-нибудь, пожалуйста, проясните, если мне что-то здесь не хватает.

12
ответ дан 30 November 2019 в 12:36
поделиться

Что произойдет, если возникшее событие не завершится до тех пор, пока процесс не выйдет из области действия этой локальной переменной? Переменная была бы освобождена, и ваш поток завершился бы ошибкой.

Разумный подход состоит в том, чтобы присоединить функцию делегата, которая указывает родительскому потоку, что подпоток завершился.

2
ответ дан 30 November 2019 в 12:36
поделиться

В большинстве сценариев локальные переменные относятся к потоку, поэтому проблемы, связанные с volatile , совершенно не нужны.

Это меняется, когда как и в вашем примере, это «захваченная» переменная - когда она незаметно реализована как поле в классе, созданном компилятором. Так что теоретически он может быть нестабильным, но в большинстве случаев это не стоит дополнительных сложностей.

В частности, что-то вроде Monitor (также известного как lock ) с Pulse и т. Д. Могут сделать это так же хорошо, как и любое количество других конструкций потоков.

Распределение потоков сложно, и активный цикл редко является лучшим способом управления им. .


Повторное редактирование ... secondThread. Join () было бы очевидным, но если вы действительно хотите использовать отдельный токен, см. Ниже. Преимущество этого (по сравнению с такими вещами, как ManualResetEvent ) заключается в том, что он не требует ничего от ОС - он обрабатывается исключительно внутри интерфейса командной строки.

using System;
using System.Threading;
static class Program {
    static void WriteLine(string message) {
        Console.WriteLine(Thread.CurrentThread.Name + ": " + message);
    }
    static void Main() {
        Thread.CurrentThread.Name = "Main";
        object syncLock = new object();
        Thread thread = new Thread(DoStuff);
        thread.Name = "DoStuff";
        lock (syncLock) {
            WriteLine("starting second thread");
            thread.Start(syncLock);
            Monitor.Wait(syncLock);
        }
        WriteLine("exiting");
    }
    static void DoStuff(object lockHandle) {
        WriteLine("entered");

        for (int i = 0; i < 10; i++) {
            Thread.Sleep(500);
            WriteLine("working...");
        }
        lock (lockHandle) {
            Monitor.Pulse(lockHandle);
        }
        WriteLine("exiting");
    }
}
10
ответ дан 30 November 2019 в 12:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: