1

I know this has been asked many times, but I tried all solutions I found and no one works for me.

I have the following code:

    public async void setFile(QuickBrowseFile file) {
        try {
            LoggingDatabaseService db = new LoggingDatabaseService();
            LoggingData data = await db.getLoggingData(file.Id);
            db.close();
            if (data != null) {
                List<LoggingModel> loggingData = data.RowData;
                int numRows = loggingData.Count;

                Application.Current.Dispatcher.Invoke((Action)(delegate {
                    for (int i = 0; i < numRows; i++) {
                        LoggingModel m = loggingData[i];
                        treeView.Items.Add(m);//!!!!!!!!!!!!exception here
                    }
                }));
            }
        } catch (Exception ex) {
            Logger.error(ex);
        }
    }

I tried a different solution, but problem is that I have a gif image that shows some frames using the solution from How do I get an animated gif to work in WPF?.

Using the code below doesn't throw any exception, but block the gif image while loading..

var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Factory.StartNew(() => {

    LoggingDatabaseService db = new LoggingDatabaseService();
    //Console.WriteLine(file.Id);
    LoggingData data = db.getLoggingData(file.Id);
    db.close();
    if (data != null) {
        List<LoggingModel> loggingData = data.RowData;
        int numRows = loggingData.Count;
        for (int i = 0; i < numRows; i++) {
            treeView.Items.Add(loggingData[i]);
        }
    }
}, CancellationToken.None, TaskCreationOptions.None, uiContext);
Community
  • 1
  • 1
Andrei
  • 367
  • 5
  • 18
  • What is the exception you are getting on your 1st block of code? – jegtugado Oct 10 '16 at 07:31
  • Its: Exception thrown: 'System.Windows.Markup.XamlParseException' in PresentationFramework.dll Additional information: Must create DependencySource on same Thread as the DependencyObject. – Andrei Oct 10 '16 at 07:47
  • You can try passing the synchronization context to your `Task.Factory.StartNew` like `var uiContext = TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, uiContext);`. Tasks are created on background threads, see if this helps. – jegtugado Oct 10 '16 at 08:06
  • Why do you want to move the `treeView.Items.Add(m)` to a separate worker? This shouldn't be the slow part of your code, unless your design is flawed. – grek40 Oct 10 '16 at 08:11
  • Can you modify your code to produce this behavior without accessing external data (verifyable example)? – grek40 Oct 10 '16 at 08:17
  • The slow part is db.getLoggingData(file.Id) - it takes some time to get data from the database. @Ephraim I tried this solution, but I can't use await db.getLoggingData(file.Id) because of the error that I should use async.. I'm new to WPF and C#, so maybe I'm missing something here. – Andrei Oct 10 '16 at 08:21
  • Could it be that you don't create `treeView` in the dispatcher thread? – haindl Oct 10 '16 at 08:59
  • treeView is added using XAML, so its: – Andrei Oct 10 '16 at 09:56
  • If the slow part is `db.getLoggingData(file.Id)`, then you should be concerned about moving having this action out of the UI thread context. What is the code behind `getLoggingData`? – grek40 Oct 11 '16 at 06:22
  • `getLoggingData` reads data from the database. The first version loads data in a different thread, non UI but when adding items it fails with the exception in the title. Second version doesn't throw any exceptions, but blocks UI thread. – Andrei Oct 11 '16 at 09:50
  • What is the code behind `getLoggingData`? What are the exact return types? Can't you just run-await a task that calls the code before `if (data != null)` and process the rest without any special thread? Where is `setFile` called from? `setFile` doesn't look like an event handler, so it shouldn't be `async void`... – grek40 Oct 11 '16 at 18:43
  • `setFile` is called from the constructor of the parent window. `getLoggingData` returns an object with some data from DB. I think the first version provided does what you suggest - waits for a task and then create the UI, but it fails with the error in the title. – Andrei Oct 13 '16 at 05:15
  • Does this answer your question? [Error: Must create DependencySource on same Thread as the DependencyObject even by using Dispatcher](https://stackoverflow.com/questions/26361020/error-must-create-dependencysource-on-same-thread-as-the-dependencyobject-even) – ˈvɔlə Mar 17 '23 at 14:37

0 Answers0