{"id":110960,"date":"2025-03-12T07:00:00","date_gmt":"2025-03-12T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110960"},"modified":"2025-03-12T08:30:22","modified_gmt":"2025-03-12T15:30:22","slug":"20250312-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250312-00\/?p=110960","title":{"rendered":"What are the thread safety requirements of <CODE>HSTRING<\/CODE> and <CODE>BSTR<\/CODE>?"},"content":{"rendered":"<p>Among the proliferation of string types are the <code>HSTRING<\/code> (represented in C++\/WinRT as <code>winrt::<wbr \/>hstring<\/code> and in C++\/CX as <code>String^<\/code>) and the <code>BSTR<\/code>. What are the threading rules for these string types?<\/p>\n<p>These string types are not COM objects, so the restrictions on COM objects do not apply. These are just blocks of memory that have freestanding functions for manipulating them (such as <code>Sys\u00adAlloc\u00adString<\/code> and <code>Sys\u00adFree\u00adString<\/code> for <code>BSTR<\/code>; <code>Windows\u00adCreate\u00adString<\/code> and <code>Windows\u00adDelete\u00adString<\/code> for <code>HSTRING<\/code>). You are welcome to call any method from any thread.<\/p>\n<p>The rules for <code>BSTR<\/code> are that read operations (like <code>Sys\u00adGet\u00adString\u00adLen<\/code>) can operate concurrently. But no read operations can operate concurrently with a write operation, so you cannot do a <code>Sys\u00adGet\u00adString\u00adLen<\/code> at the same time as a <code>Sys\u00adRe\u00adAlloc\u00adString<\/code>, for example, and you can&#8217;t modify the string contents on one thread while reading them from another.<\/p>\n<p>Windows Runtime <code>HSTRING<\/code>s are immutable, so there are no write operations. This makes the rules simpler: Once you create an <code>HSTRING<\/code> (until you destroy it), all operations are thread-safe.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>They do not have thread affinity.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-110960","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>They do not have thread affinity.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110960","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=110960"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110960\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=110960"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110960"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110960"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}