Платформа.NET: квартира объектов связывается?

Попробуйте это

.inp {
  box-sizing:border-box;
}
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<form>
<input type='text' style="width:250px" class= "inp">
<div style='width:250px;background-color:#00FF00'>&nbsp;</div>

</form>
</body>
</html>

7
задан 8 revs 27 January 2009 в 15:39
поделиться

7 ответов

СТРЕЛЬБА для щедрости!

Хорошо, некоторые классы/платформы классов в.NET имеют методы, которые являются связанной квартирой, но ДИЗАЙНОМ ТОЛЬКО. Это означает, что необходимо КОНКРЕТНО КОДИРОВАТЬ, чтобы сделать это. Не набор по умолчанию. Кодирование для этого довольно топорно. Необходимо получить идентификатор потока, с которым Вы хотите придерживаться и проверить все это время. Я не думаю, что существуют любые средства в платформе, которая делает это легким кроме средств для компонентов UI, отслеживающих поток UI. Та платформа поддержки, вероятно, прокладывается под землей глубоко в стеке UI; я никогда не видел его ни в каких документах MSDN.

То, что более распространено, устанавливает квартиру потока. Много частей всей платформы ограничивается потоками STA дизайном (STAThreadAttribute). Это обычно, потому что они, в глубине души в их базовых, сенсорных COM-объектах, которые часто требуют, чтобы они только использовались в потоках STA. Например, основной поток в приложениях winforms отмечен с STAThreadAttribute, так, чтобы каждый компонент UI мог только быть затронут в том же потоке, они создаются, поток UI. Интересно, XamlReader в WPF знает о квартире текущего потока и даже не десериализует компоненты UI, если поток его выполнение в не является потоком STA.

"Стандарт постепенно имеет привязку потока или заботится, распараллеливает ли в STA или MTA?" Ответ не, если Вы не кодируете его, чтобы быть так или отметить его методы с STAThreadAttribute или если объект инстанцируют в стеке вызовов, которому, где-нибудь в его иерархии, отметили метод с STAThreadAttribute.

"Объект ADO.NET имеет привязку потока и является ею знающая квартира?"

Ну, DbConnection расширяется от Компонента, который расширяет MarshalByRefObject. Компонент, MBRO, DbConnection и его потомки (т.е. SqlConnection) не содержат методов, которые отмечены с STAThreadAttribute. Быстрая проверка их главных зависимостей (таких как DbTransaction) не находит, что любой из методов ТЕХ классов отмечен как STA только также. Поэтому они не знающая квартира.

Быстрый обзор с Отражателем не находит очевидного наблюдения идентификатора потока. DbConnection действительно зависит от Транзакции, которая походит на наиболее вероятный поток-fondler набора.

Я вспыхнул Отражатель и проверил несколько из этих классов.
DbConnection - Не заботится об идентификаторе текущего потока
SqlConnection - Делает некоторое отслеживание потока при отладке
SqlTransaction - Имеет функцию под названием "ZombieCheck", но никакое наблюдение потока
DbTransaction - Ничто здесь.

Таким образом, я думаю, что его сейф говорит, что объекты ADO.NET НЕ имеют привязки потока. Я даже не видел, что они использовали Поток. Begin/EndThreadAffinity.


Править

Как указано в комментариях Jeremy, я продолжал говорить о КЛАССАХ, отмечаемых с атрибутом, а не МЕТОДАМИ КЛАССОВ. Ошибка HUUUGE. Я завинтил большой успех путем произведения впечатления, что я только посмотрел на определения классов, а не весь класс.

Я отредактировал это, чтобы разъяснить, и позволить мне сказать это здесь, чтобы быть абсолютно ясным: Никакие методы класса в Системе. Данные отмечены с STAThreadAttribute. Можно проверить это на себя со следующим кодом hacky:

SqlConnection sc = new SqlConnection();
var data = AppDomain.CurrentDomain.GetAssemblies()
           .Where(x => x.FullName.StartsWith("System.Data,")).First();
var dtypes = data.GetTypes();
var results = new List<string>();
foreach (var type in dtypes)
    foreach (var method in type.GetMethods())
        foreach (var attr in 
                method.GetCustomAttributes(true).OfType<System.Attribute>())
        {
            results.Add(string.Format("{0} {1} {2}", 
                               type.Name, method.Name, attr.GetType().Name));
            if (attr.GetType() == typeof(STAThreadAttribute)) 
                                           throw new Exception("SHIII");
        }

Кроме того, классы UI в winforms также не используют STAThreadAttribute; это - приложение, где этот атрибут используется (как, снова, указал Jeremy).

Существует особый случай, где я столкнулся с классом, являющимся знающей квартирой. XamlReader, который десериализовывает xaml и создает классы UI WPF, выдаст исключение, когда его метод Загрузки назовут на потоке MTA. Даже в документах, который является раздражающим... Так, снова, классы не являются квартирой, знающей по умолчанию; необходимо кодировать его тот путь, или необходимо проинформировать их экземпляры newing их в цепочке метода, содержащей метод, отмеченный STAThreadAttribute. Ух. Этот материал более трудно объяснить, чем понимают...

3
ответ дан 7 December 2019 в 05:32
поделиться

Объекты.NET не связываются с квартирой. Квартиры только действительно играют роль, когда Ваш код.NET взаимодействует с COM-объектами, хотя это не трудно сделать невольно. Например, если Вы взаимодействуете с буфером обмена Windows, Вы активируете подсистему COM. Квартиры установлены на уровне потока, и после того как Ваш поток установил свою квартиру (MTA, STA, и т.д.) он не может измениться, таким образом, очень важно получить корректную квартиру. Все приложения WinForms имеют [STAThread], присоединенный к их Основному () метод, чтобы гарантировать, что поток главного приложения (т.е. сообщение GUI, качающее поток), является STA и может взаимодействовать с теми удобными средствами как буфер обмена Windows.

Время выполнения.NET должно знать о подсистеме COM для обеспечения взаимодействующей с COM функциональности. Это довольно редко, хотя нуждаться во внутренних ужасных деталях.

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

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

Например, предположите, что Вы хотите использовать COM-объект в своем новом многопоточном приложении C++. Этот COM-объект был разработан в Visual Basic и не ориентирован на многопотоковое исполнение, но Вы хотите использовать несколько экземпляров того компонента от нескольких потоков. В то время как это верно, что Вы могли добавить некоторый механизм блокировки для предотвращения неподходящего доступа, то, что объект существует в своей собственной Единственной квартире потока (STA), означает, что подсистема COM сериализирует доступ к объекту от Вашего имени. Вы не должны знать, что модель потоков COM-объекта использует его, или по крайней мере который является способом, которым это обычно работает.

.NET была записана для нашего нового многопоточного мира и как таковая, не использует понятие квартир. Время выполнения определенно знает о них и должно быть, для поддержки interop с COM-объектами прежней версии.

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

Если Вы хотите некоторую информацию о действительно ядре, Вы могли бы проверить Квартиры и Качающий в CLR.

4
ответ дан 7 December 2019 в 05:32
поделиться

Почему Вы хотели бы создать соединение на одном потоке и использовать его от другого?

Время между созданием соединения / открытый и закрывается/располагает, должно быть минимальным, как возможно, так передает, оно к другому потоку не походит на хорошую идею независимо от действительно ли его возможное.

0
ответ дан 7 December 2019 в 05:32
поделиться

Прежде всего Вы не обязаны синхронизировать свой доступ к объектам в многопоточных сценариях. Можно свободно "играть" с любыми членами собственных классов от нескольких потоков без каких-либо ограничений от CLR. Факт Форма (и Средства управления в целом) не позволяет, Вы для вызова участников на другом потоке являетесь деталью реализации (и тот, который не был явным перед.Net 2.0).

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

На Вашем конкретном вопросе. Я полагаю, что SqlConnection может использоваться от нескольких потоков, но не одновременно. Быть неспособностью для параллельного использования SqlConnection почти завершается, инвертирует любой выигрыш в производительности, который можно получить при помощи общего соединения. Учитывая то, как дешевый это должно создать новый SqlConnection (особенно, после того как соединение объединено), имеет очень мало смысла снова использовать соединение как это.

0
ответ дан 7 December 2019 в 05:32
поделиться

Объекты в.NET не ограничены квартирой, если Вы конкретно не делаете их так.

Например, при использовании локальной памяти потока Вы собираетесь иметь проблемы с несколькими потоками, получающими доступ к объекту, пока Вы предполагаете, что весь доступ к объекту произойдет на одном потоке.

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

Что касается Ваших других случаев, давайте возьмем их по одному с комментариями:


Но что относительно произвольных объектов? Что относительно:

public class MyClass
{
    int _number;

    public int Number { get { return _number; } set { _number = value; } }
}

MyClass myObject = new MyClass();

Пока я синхронизирую доступ к myObject, двум потокам позволяют говорить с ним?

Ответ: Да, и в этом случае потребность в синхронизации зависит от Ваших требований.

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

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

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

Для более сложного объекта скажите установку структуры, больше, чем собственный размер шины CPU (т.е. больше, чем 32 или 64-разрядный, завися), блокировка требуется, начиная с копирования данных в правильное пятно в памяти не атомарная операция в таком случае. Другими словами, без блокировки Вы рискуете читать половину старой половины новых данных, если один поток пытается считать данные посреди операции записи, выполняющейся на другом потоке.


То же идет для:

List<Object> sharedList = new List<Object>();

Два потока могут говорить со списком, пока они не делают этого одновременно, обычно с:

lock (sharedList)
{
    sharedList.Add(data);
}

двум потокам позволяют коснуться того же объекта?

Ответ: Да. Это обычно - хорошая идея использовать свойство SyncRoot интерфейса ICollection на наборах или просто использовать другой объект блокировки в целом.


То же идет для:

IAsyncResult ar = BeginSetLabelToTheValueINeed(label1);
...
EndSetLabelToTheValueINeed(ar);

Ответ: Этот, в котором я не уверен, какой проблематичное является переменным здесь? Если label1 затем нет ничего здесь, которое предотвращает несколько доступов потоков и питания с этой переменной, и Вы обязаны использовать механизмы блокировки для предотвращения таких проблем.


То же идет для:

//Fetch image on connection that is an existing DB transaction
public static Bitmap GetImageThumbnail(DbConnection conn, int imageID) 
{
}

будучи преобразованным в асинхронный шаблон делегата:

//Begin fetching an image on connection that is an existing DB transaction
IAsyncResult ar = BeginGetImageThumbnuts(conn, imageID, callback, stateOjbect);
...
//Finish fetching an image on connection that is an existing DB transaction
Bitmap thumb = EndGetImageNumbthail(ar);

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

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


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

1
ответ дан 7 December 2019 в 05:32
поделиться

Посмотрите эту удобную страницу от Alik Levin

http://blogs.msdn.com/alikl/archive/2008/06/20/pitfalls-with-net-multithreading-and-com-objects-threads-must-have-compatible-apartment-models-mta-vs-sta.aspx

.net Object является смоделированный MTA. и это - только concearn, если Вы взаимодействуете с COM-объектами

Ловушки с.Net Multithreading And COM Objects – потоки должны иметь совместимые модели квартиры (MTA по сравнению с STA)

Будьте внимательны при реализации многопоточности .NET в сочетании с COM-объектами. Вопрос моделей квартиры потока.

Потоки .NET имеют модель Multi Threaded Apartment (MTA) по умолчанию. COM-объекты имеют Единственную квартиру потока (STA). Обращение к COM-объектам на потоках .NET, которые Вы порождаете, может вызвать непредсказанный результат.

Многопоточность в .NET легко реализована или на основе объектов Потока или на основе ThreadPool. Поток. Запустите (), метод порождает новый поток, который имеет модель Multi Threaded Apartment (MTA). ThreadPool. QueueUserWorkItem (myMethod) очереди myMethod, чтобы быть выполненным на доступном потоке, управляемом им.

0
ответ дан 7 December 2019 в 05:32
поделиться

Существует только несколько вариантов использования, которые я знаю для желания вышеупомянутого:

  • Работа с SqlCe, поскольку это - прием производительности
  • Работа с NHibernate и хранение соединения, живого все время (хотя это в основном против лучшей практики NHibernate),

Кроме тех двух (плюс, возможно, немногие другие?) Вы действительно не хотите делать то, что Вы спрашиваете здесь.

Я соглашаюсь с StingyJack, в большинстве случаев Ваши объекты ADO должны казаться в рамках использований (созданными и уничтоженными в объеме) и быть локальными переменными, таким образом, устраняющими проблемы потока.

Соглашение с WinForm относится к различию между POST, и ОТПРАВЬТЕ, сообщения (отправьте блок сообщений потребителю, пока они не завершаются). В действительности это не выдает исключение, исключением является просто предупреждение, добавленное в 2,00 в отладке. На практике без исключения это приводит к (на вид) случайным взлетам блокировки.

0
ответ дан 7 December 2019 в 05:32
поделиться
Другие вопросы по тегам:

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