Пишите из фоновой ветки, читайте из пользовательского интерфейса - PullRequest
0 голосов
/ 28 апреля 2011

У меня есть фоновый поток, выполняющий некоторую работу, и пользовательский интерфейс, отображающий прогресс, и по разным причинам я не использую фонового работника;вместо этого Timer запускает обновления пользовательского интерфейса.

Я вообще не использую Invoke вызовы.Вместо этого фоновый процесс записывает в массив из 4 строк.Этот массив объявлен как член экземпляра моей главной формы.

Нужно ли использовать блокировки для чтения этого массива из потока пользовательского интерфейса?Можно ли писать в массив из фонового потока и читать из него из интерфейса без каких-либо дополнительных мер предосторожности?

EDIT : MSDN читает "The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock."Не означает ли это, что блокировка будет препятствовать запуску одного и того же блока кода двумя разными потоками?

Ответы [ 3 ]

1 голос
/ 28 апреля 2011

Задумывались ли вы о том, что произойдет, если читатель читает, а писатель изменяет его?

Вам следует использовать lock, как в читателе, так и в писателе .

Если вы просматриваете и модифицируете любой другой ресурс из разных потоков, то же самое.Вы должны заблокировать один и тот же объект, чтобы избежать вторичных эффектов ...

Лучшая ссылка, которую я нашел о многопоточности вообще в C #, - это следующая книга:

Потоки в C # , Джозефом Альбахари

Там вы найдете множество примеров, подобных этому.

Вы можете прочитать это онлайн , и я предлагаю вам сделать это, потому чтоэто занимает много тем, связанных с многопоточностью, таких как Monitor.Enter и другие

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

Вместо того, чтобы делать:

public void UpdateTextBox(string text) {
    textBox1.Text = text;
}

, вы можете сделать:

public void UpdateTextBox(string text) {
    MethodInvoker m = () => { textBox1.Text = text; };

    //The following lines can be encapsulated in a method, in case you need to use it again in other methods...
    if (InvokeRequired) {
        BeginInvoke(m);
    }
    else {
        m.Invoke();
    }
}
1 голос
/ 28 апреля 2011

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

//lock sync object in your form 
private object sync = new object();

в методе письма и в методе чтения.

lock (sync)
{
    //access the array here
}
1 голос
/ 28 апреля 2011

Быстрый ответ заключается в том, что вам нужно использовать блокировки, если у вас есть несколько потоков, которые одновременно записывают в ваш массив строк. Вот ссылка на последнюю ссылку на блокировки для c # http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=VS.100%29.aspx.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...