Действительно блокирует () {}, блокируют ресурс, или он блокирует часть кода?

Согласно вашему коду, вы инициализируете экран MyHomePage в верхней части текущего экрана (начиная с нового экрана). При навигации по ящикам вы должны заменить body: на экраны, которые вы хотите показать.

Пример:

Возьмите переменную типа

  int selectionScreen = 0;

, вы можете взять ее в соответствии со своими потребностями, я взял int. Теперь на основе этого вы можете выбрать, какой экран вы хотите показать.

new Scaffold(
        appBar: new AppBar(
          // here we display the title corresponding to the fragment
          // you can instead choose to have a static title
          title: new Text("Drawer navigation"),
        ),
        drawer: new Drawer(
          child: new Column(
            children: <Widget>[
              new ListTile(
                  leading: Icon(Icons.home),
                  title: new Text("Home"),
                  onTap: () {
                    setState(() {
                      selectionScreen = 0;
                    });
                    Navigator.pop(context);
                  })
            ],
          ),
        ),
        body: _getScreen(selectionScreen));

Теперь вы можете использовать _getScreen(), чтобы получить несколько экранов, так как вы добавляете больше ListTile в список ящиков.

_getScreen(int selection) {
    switch (selection) {
      case 0:
        return MyHomePage();

      case 1:
        return Screen2();
      default:
    }
  }

Это заменит экраны в существующем навигационном экране ящика.

Пожалуйста, подтвердите, если это была проблема, с которой вы столкнулись. Спасибо.

16
задан Shog9 15 April 2009 в 19:02
поделиться

7 ответов

Большинство других ответов относятся к вашему примеру кода, поэтому я постараюсь ответить на ваш вопрос в заголовке.

Замок - это просто знак. Тот, у кого есть знак, может выйти на сцену, так сказать. Таким образом, объект, на который вы блокируете, не имеет явного соединения с ресурсом, вокруг которого вы пытаетесь синхронизироваться. Пока все читатели / писатели согласны с одним и тем же маркером, это может быть что угодно.

При попытке заблокировать объект (то есть, вызвав Monitor.Enter для объекта), среда выполнения проверяет, удерживается ли блокировка потоком. В этом случае поток, пытающийся заблокировать, приостанавливается, в противном случае он получает блокировку и продолжает выполнение.

Когда поток, удерживающий блокировку, выходит из области блокировки (т.е. вызывает Monitor.Exit ), блокировка снята, и любые ожидающие потоки могут теперь получить блокировку.

Наконец, несколько вещей, которые следует иметь в виду в отношении замков:

  • Блокируйте столько, сколько вам нужно, но не больше.
  • Если вы используете Monitor.Enter / Exit вместо ключевого слова lock , обязательно сделайте вызов Exit в finally , поэтому блокировка снимается даже в случае исключения.
  • Обнаружение объекта для блокировки затрудняет получение обзора того, кто и когда блокируется. Идеально синхронизированные операции должны быть инкапсулированы.
12
ответ дан 30 November 2019 в 21:54
поделиться

Да, использование блокировки является правильный путь Вы можете заблокировать на любом объекте,

5
ответ дан 30 November 2019 в 21:54
поделиться

Оба блока кода здесь заблокированы. Если первый поток блокирует первый блок, а второй поток пытается попасть во второй блок, ему придется подождать.

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

Будет ли блокировка справки в обоих случаях? Да.

Lock () {} блокирует ресурс или он блокирует кусок кода?

lock(o)
{
  // read from resource    
}

является синтаксическим сахаром для

Monitor.Enter(o);
try
{
  // read from resource 
}
finally
{
  Monitor.Exit(o);
}

Класс Monitor содержит коллекцию объектов, которые вы используете для синхронизации доступа к блокам кода. Для каждого объекта синхронизации Monitor хранит:

  1. Ссылку на поток, который в данный момент удерживает блокировку на объекте синхронизации; то есть очередь выполнения этого потока.
  2. «Готовая» очередь - список потоков, которые блокируются, пока им не будет предоставлена ​​блокировка для этого синхронизирующего объекта.
  3. «Ждущая» очередь - список потоков, которые блокировать, пока они не будут перемещены в «готовую» очередь с помощью Monitor.Pulse () или Monitor.PulseAll () .

Итак, когда поток вызывает блокировку (o), он помещается в очередь готовности o до тех пор, пока ему не будет дана блокировка для o, после чего он продолжит выполнение своего кода.

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

Оператор lock (o) {...} скомпилирован в это:

Monitor.Enter(o)
try { ... }
finally { Monitor.Exit(o) }

Вызов Monitor.Enter () заблокирует поток, если другой поток уже вызвал его. Он будет разблокирован только после того, как другой поток вызовет Monitor.Exit () для объекта.

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

И это должно сработать при условии, что у вас задействован только один процесс. Вы захотите использовать «Mutex», если хотите, чтобы он работал более чем в одном процессе.

Да, и объект «o» должен быть одноэлементным или иметь область видимости везде, где нужна блокировка, как то, что ДЕЙСТВИТЕЛЬНО заблокирован этот объект, и если вы создадите новый, то этот новый еще не будет заблокирован.

0
ответ дан 30 November 2019 в 21:54
поделиться

То, как вы это реализовали, является приемлемым способом сделать то, что вам нужно. Один из способов улучшить ваш способ сделать это - использовать lock () в самом словаре, а не второй объект, используемый для синхронизации словаря. Таким образом, вместо того, чтобы передавать лишний объект, сам ресурс отслеживает наличие блокировки на собственном мониторе.

Использование отдельного объекта может быть полезно в некоторых случаях, например, при синхронизации доступа к внешним ресурсам, но в подобных случаях это накладные расходы.

0
ответ дан 30 November 2019 в 21:54
поделиться
Другие вопросы по тегам:

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