🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Threading bug
This page was created by Hans.karlsen on 2021-02-19. Last edited by Wikiadmin on 2026-07-29.

You can use this page to recognize the historical incomplete-file-write threading defect and ensure that asynchronous application threads do not abandon list enumeration while a temporary lock is held.

Status

The disappearing ViewModel columns and incomplete file writes described on this page were fixed in January 2021.

The defect could occur when parallel file-write work ran with AsyncServiceSupportThreadInfo.InAsyncThreadOrTheMainThreadInNonAsyncAppSoYouCanNeverGiveUp set to false. An enumeration that encountered a longer-lived lock could then give up and return fewer items than were actually present. File writing could consequently persist incomplete data.

Earlier failures that reported a failed save and asked you to try again may have had the same underlying cause. A later change suppressed that failure but could result in incomplete writes; the January 2021 fix addresses that more serious outcome.

Why enumeration can give up

In an asynchronous UI application, the UI must remain responsive while an asynchronous thread completes work. Enumeration can therefore give up when it cannot obtain a temporary lock promptly, trusting that the asynchronous thread will later supply the missing data.

That behavior is not acceptable for work that must enumerate a complete list before writing data. For example, if a file writer enumerates the columns of a ViewModel while another thread holds a lock, a partial enumeration can produce a file that is missing columns.

Required setting

To ensure that your application does not give up list iterations because of temporary locks, set the existing thread-static flag to true:

AsyncServiceSupportThreadInfo.InAsyncThreadOrTheMainThreadInNonAsyncAppSoYouCanNeverGiveUp = true;

Set the flag on the thread that performs the work, before that thread starts enumerating lists or writing files. The field is marked [ThreadStatic], so its value is specific to each thread. Setting it on one thread does not set it for parallel worker threads.

Apply the setting for parallel work

  1. Identify each asynchronous or parallel thread that enumerates framework lists as part of a complete write operation.
  2. Before the thread starts that operation, assign true to AsyncServiceSupportThreadInfo.InAsyncThreadOrTheMainThreadInNonAsyncAppSoYouCanNeverGiveUp on that thread.
  3. Run the operation under the locking or concurrency conditions that previously caused missing ViewModel columns or failed saves.
  4. Verify the written result contains every expected item, not only the items that were available before a lock was encountered.

Do not add a second declaration of AsyncServiceSupportThreadInfo to your application. Use the type and field supplied by the MDriven framework.

Field behavior

The framework field is declared as thread-static and has a default value of true:

public static class AsyncServiceSupportThreadInfo
{
  /// <summary>
  /// Will return true when called from a thread that is an active async-thread in an EcoSpace.
  /// </summary>
  [ThreadStatic]
  public static bool InAsyncThreadOrTheMainThreadInNonAsyncAppSoYouCanNeverGiveUp = true;
}

For non-asynchronous applications, the main thread has the same status as an asynchronous thread for this purpose: it must not give up the enumeration.

Troubleshooting scope

This issue concerns incomplete enumeration caused by temporary locks during parallel work. It is not a general explanation for every design-time, code-generation, cache, or UI problem.

If the symptom occurs in a Blazor host, also review the dispatcher and threading guidance in Documentation:Blazor. For model or generated-code errors, use Documentation:Codegen failed. For changes that may alter framework behavior between versions, review Documentation:Breaking changes.

See also