MVVM and Multithreading in C#



  • So, I'm using an MVVM framework (Prism + Unity) for my UWP Windows 10 App and recently had an idea on a new feature which would require a second window. Doing just that is easy, it's just a few lines of code and works flawlessly, like this:

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        CoreApplicationView newView = CoreApplication.CreateNewView();
        int newViewId = 0;
        await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            Frame frame = new Frame();
            frame.Navigate(typeof(SecondaryPage), null);   
            Window.Current.Content = frame;
            Window.Current.Activate();
    
            newViewId = ApplicationView.GetForCurrentView().Id;
        });
        bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
    }
    

    What does not work so flawlessly, however, is coupling those new frames to the MVVM framework - because that new Window (and its frames) live in a new thread. Which means that if I try to take the easy approach and simply let Prism autowire things, the app will crash because of a cross-thread data access attempt (makes sense).

    Does anyone have an idea on how to go from here? I'm a bit inexperienced in that matter (and it doesn't help that searching for anything with "Unity" in its name will yield umpteenth results for Unity3D).


  • FoxDev

    @Rhywden I have to ask: is there a reason you're putting the new window in a different thread?



  • @RaceProUK said in MVVM and Multithreading in C#:

    @Rhywden I have to ask: is there a reason you're putting the new window in a different thread?

    I don't have much of a choice about it - that's the only way it works. I mean, there's only one other way to do multiple windows/screens and that's the ProjectionView - but that's a) only meant for non-interactive stuff (as the name implies) and b) it also spawns in its own thread.

    I mean, it does make sense - you don't want the UI of your second view to be able to block the UI of your main view. But still :)


  • Impossible Mission - B

    @Rhywden said in MVVM and Multithreading in C#:

    I mean, it does make sense - you don't want the UI of your second view to be able to block the UI of your main view.

    That still doesn't make sense. Delphi's been doing multiple independent windows on the same thread for 20+ years now. You can choose to have them block (modal dialogs) if you want, but by default they don't; you can open an arbitrary number of windows without trouble.

    Of course, if you do a long-running operation on the main thread, it will block all the UI, but since you're using C# with async/await, that shouldn't be a problem.

    So... back to @RaceProUK's question. Or, to put it a different way,



  • @masonwheeler Listen, guys, I put this in CodeHelp so you can attempt to help or fuck off.

    I already stated so but I guess I'll need to state again: THIS IS THE ONLY, OFFICIAL WAY TO OPEN A SECOND WINDOW IN UWP APPS.

    Only, as in: Singular. No other option. So, either you state something that helps or you can fuck off. The Garage is another category.


  • FoxDev

    @Rhywden Well, if you're going to be like that about it, then you won;t be getting any help from me.

    Good day.



  • @RaceProUK said in MVVM and Multithreading in C#:

    @Rhywden Well, if you're going to be like that about it, then you won;t be getting any help from me.

    Good day.

    Yes, because @masonwheeler was sooo helpful to begin with:

    Me: This is the way one opens a new window in UWP
    You: Why would you do it that way?
    Me: Because that's the only way to do it.
    @masonwheeler : Why would you do that? posts an insulting meme picture
    Me: Because that's the only way to do that?


  • Impossible Mission - B

    @Rhywden You didn't say that's the way you open a new window in UWP. You said that that's the way you were opening it with that framework. Then you said that it wasn't working. @RaceProUK and I explained that yeah, you probably shouldn't expect that to work, and you accuse us of being insulting?


  • Banned

    I tried googling "uwp two windows one thread", but was unable to find anything because Google thinks "one thread" and "multiple threads" are synonymous.



  • @masonwheeler said in MVVM and Multithreading in C#:

    @Rhywden You didn't say that's the way you open a new window in UWP. You said that that's the way you were opening it with that framework. Then you said that it wasn't working. @RaceProUK and I explained that yeah, you probably shouldn't expect that to work, and you accuse us of being insulting?

    No, I said that it was opening using this way and when I tried to wire in the framework, then it would crash. I also posted a code snippet which mentions neither Unity nor Prism.



  • @Rhywden I've never used Unity, but I might suggest that visiting their Github/forum/etc and asking there might be a better idea than asking here (at this point, anyway). There's too many frameworks out there, and apparently nobody on here knows this one. Maybe somebody here will know, but it's the weekend, so you'll probably have to wait until the Monday rush for them to even see your question.

    Post WTFs if they tell you any. 😸



  • @Captain Yeah, did that two hours ago. If nothing else helps, I'll have to create something that ensures that only one thread can write to the data layer at a time because that one's currently using SQLite which is not exactly happy when two threads try to do stuff concurrently.


  • Banned

    @Rhywden maybe the solution is just get rid of cross-thread data access? Which part of MVVM is problematic - model, view, viewmodel, or the glue inbetween? Because if it's either model or viewmodel, it should be relatively easy to isolate all shared data and have structured way of accessing it, with channels or whatever. And if it's glue, then change your glue because it's inherently broken.


  • Garbage Person

    You're not writing a webapp and therefore nobody has considered your use case. Web browsers can't have multiple windows so neither can you.


  • Banned

    @Weng actually, I know a browser game that requires you to open it twice and play in two windows at once to get 100% completion.

    Unless you mean it like @end when he said there are no topics 10,000 posts long.


  • Garbage Person

    @Gąska That must not be written entirely in jubbuhscrip and therefore is old fashioned and irreverent.

    Edit: Christ, I forgot Node exists.


  • Discourse touched me in a no-no place

    @Rhywden said in MVVM and Multithreading in C#:

    using SQLite which is not exactly happy when two threads try to do stuff concurrently

    Should be OK these days, provided you're not doing a write-heavy workload. Write-heavy workloads can suffer performance degradation.

    (Depends on the compilation flags used when building and also the connection flags, so you may need to investigate in detail.)



  • @Weng said in MVVM and Multithreading in C#:

    Web browsers can't have multiple windows so neither can you.

    http://weareinstrument.com/ball/


  • Notification Spam Recipient

    @ben_lubar said in MVVM and Multithreading in C#:

    @Weng said in MVVM and Multithreading in C#:

    Web browsers can't have multiple windows so neither can you.

    http://weareinstrument.com/ball/

    Doesn't seem to work on mobile, the ball just sits there all sad like...


  • Banned

    @Weng said in MVVM and Multithreading in C#:

    @Gąska That must not be written entirely in jubbuhscrip and therefore is old fashioned and irreverent.

    Even better - Adobe Flash!


  • :belt_onion:

    @Rhywden said in MVVM and Multithreading in C#:

    THIS IS THE ONLY, OFFICIAL WAY TO OPEN A SECOND WINDOW IN UWP APPS.

    Only, as in: Singular. No other option.

    Well, then, I guess you have answered your own question.

    Rhywden: How do I open a second window?

    The Universe: Sorry, you're fucked.



  • @Captain said in MVVM and Multithreading in C#:

    @Rhywden I've never used Unity, but I might suggest that visiting their Github/forum/etc and asking there might be a better idea than asking here (at this point, anyway). There's too many frameworks out there, and apparently nobody on here knows this one. Maybe somebody here will know, but it's the weekend, so you'll probably have to wait until the Monday rush for them to even see your question.

    I've noticed stack overflow is becoming less useful for this exact reason.

    These days I usually go directly to github issues.

    BTW I don't know the answer to OP question, but I'm curious to learn.


  • Banned

    @cartman82 said in MVVM and Multithreading in C#:

    These days I usually go directly to github issues.

    Aren't Github issues for things that don't work at all? Or is the percentage of idiots significant enough that there's lots of basic tutorials over there?



  • @Gąska said in MVVM and Multithreading in C#:

    Aren't Github issues for things that don't work at all? Or is the percentage of idiots significant enough that there's lots of basic tutorials over there?

    I've seen a lot of pure question threads. The maintainers answer the question, sometimes tag it as "feedback", and close the thread. Some are still directing people towards stack overflow, but it's a losing battle IMO. If I have an issue with library X, who better to help me than the author of library X?


  • Banned

    @cartman82 it'd actually be a cool idea for GitHub to have dedicated Q&A section for projects.



  • @Rhywden said in MVVM and Multithreading in C#:

    using SQLite which is not exactly happy when two threads try to do stuff concurrently

    Use a third thread to do the SQLite stuff, then make every other thread talk to it?

    I'm baffled at how everything STILL seems designed for a single-threaded model.

    That world ended 10 years ago, people! Cores are not going to get any faster! The only place we're going from here is dozens of cores, then hundreds, then who knows if thousands or millions, so better get it in your head that everything should be parallelized.



  • @cartman82 said in MVVM and Multithreading in C#:

    @Gąska said in MVVM and Multithreading in C#:

    Aren't Github issues for things that don't work at all? Or is the percentage of idiots significant enough that there's lots of basic tutorials over there?

    I've seen a lot of pure question threads. The maintainers answer the question, sometimes tag it as "feedback", and close the thread. Some are still directing people towards stack overflow, but it's a losing battle IMO. If I have an issue with library X, who better to help me than the author of library X?

    As a maintainer I mostly dislike that: if you post in a ML, forum, IRC or other user's channel, there is the chance that a user can reply, sparing some dev time. Most user don't subscribe to the issue tracker.

    The most newbie the question is, the most feels as if an entitled child is poking your back with a finger asking for inmediate attention .



  • @cabrito said in MVVM and Multithreading in C#:

    As a maintainer I mostly dislike that: if you post in a ML, forum, IRC or other user's channel, there is the chance that a user can reply, sparing some dev time. Most user don't subscribe to the issue tracker.

    So clearly the rational choice would be to combine the bug tracker and the official forum, so both mods and users can answer.....

    ...

    ...

    :doing_it_wrong: ❗


  • Discourse touched me in a no-no place

    @anonymous234 said in MVVM and Multithreading in C#:

    I'm baffled at how everything STILL seems designed for a single-threaded model.

    Single-threaded is a lot easier for people to think about. Failing that, the next easiest model to handle is message passing (which includes a lot of different sorts of things). For reasons unknown to me, lots of programmers instead jumped on the model where memory is shared and every thread is able to scribble anywhere it wants, and that's just about the most complicated parallelism model I can think of because it requires everyone to be extremely well-behaved. It's also by far the most expensive in terms of hardware, being almost impossible to scale beyond a thousand simultaneous threads (a figure that's worse with poor programming) and that's a tiny fraction of what hardware is capable of…

    But we're stuck with lots of people's bad decisions and the fact that single-threaded stuff is one heck of a lot simpler to think about. (Also, SQLite appears to be a lot better behaved in multithreaded apps than it used to be, something I've learned this weekend…)



  • @Rhywden You probably won't listen but you will need to probably deal with something like Synchronisation context or have a callback to a C# event handler.

    Also you are going to have a bad time having a second Window in any framework that is mobile first like UWP.

    However you might mean a new screen (which is a different concept), which would require some callback mechanism.



  • @dkf The whole Async / Await model is letting the CLR manage it and not the programmer. The assumption is that you take the mental head off the programmer and put it into the runtime.

    OWIN I believe runs in an event loop like node, but UWP apps won't necessarily work like that.


  • Discourse touched me in a no-no place

    @lucas1 said in MVVM and Multithreading in C#:

    The whole Async / Await model is letting the CLR manage it and not the programmer.

    And it's founded largely on message passing, though not purely. Go and Erlang (both of which I dislike for other reasons) are more strongly based on message passing. OTOH the biggest parallel system of all — the internet — is entirely based on message passing.



  • @dkf That's maybe true. But the whole point of the keywords was make it a lot easier for programmers to deal with threading / async problems.

    I can just about do it in .NET correctly pre .NET 4.0, but if it gets too complex I just have to debounce it client side and put a rate limiter via IP because I suck when it comes to concurrency.

    EDIT: It one of those things where my front end view of the world is a problem, because I tend to understand the browser better than the server.



  • @Gąska said in MVVM and Multithreading in C#:

    @cartman82 it'd actually be a cool idea for GitHub to have dedicated Q&A section for projects.

    I actually went to their GitHub site first, clicked on "New Issue" and their template suggested that for questions like mine, it might be better to ask on SO and gave an appropriate tag which they stated they'd be watching. So, let's see.



  • @cabrito said in MVVM and Multithreading in C#:

    The most newbie the question is, the most feels as if an entitled child is poking your back with a finger asking for inmediate attention .

    Most pure question threads I've started have been "what pattern do you recommend for accomplishing X with your lib". I agree that lazy RTFM questioners should go to the Stacks or RTFM.



  • @cartman82 @Rhywden is going to have to extend the lib or write a mechanism to deal with it.



  • @lucas1 Yes, I figured that. However, first I'd like to get a pointer on the most likely place to start other than implementing my own idea only to discover that there was an easier way.



  • @Rhywden If you do that will just end up in "stack overflow hell" and end up with Procrastination Paralysis.

    Also it is sometimes a good thing because you actually have to understand how the rest of everything works.



  • @cartman82 said in MVVM and Multithreading in C#:

    @cabrito said in MVVM and Multithreading in C#:

    The most newbie the question is, the most feels as if an entitled child is poking your back with a finger asking for inmediate attention .

    Most pure question threads I've started have been "what pattern do you recommend for accomplishing X with your lib". I agree that lazy RTFM questioners should go to the Stacks or RTFM.

    That's not too bad. Still, a good question with presumably a fair answer buried in the issue tracker has less community value than the same interaction in a more public channel.

    Not barking at you, just spelling my mind.

    @Gąska said in MVVM and Multithreading in C#:

    @cartman82 it'd actually be a cool idea for GitHub to have dedicated Q&A section for projects.

    Not a bad idea, especially if a post can be moved from issues to Q&A and if the thread can be also automatically forwarded to the ML



  • @cabrito No an Q&A is a bad idea it will just make the make the docs shittier.

    The code is there if you want to read it, all decent project have good docs. In .NET you can debug it if you like.

    If you find a problem, the whole Idea is that you are supposed to submit a PR. If you are unwilling or unable to do that you will pay a penalty.



  • Cross thread data access issues are usually caused by trying to access ui elements from another thread. For mvvm, that generally means that the PropertyChanged event was raised in the wrong thread, and can be worked around by calling Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher; in the main thread, and then use that dispatcher to run any code that will affect the main window from another thread.


  • Winner of the 2016 Presidential Election

    @dkf
    This is why I like the fact that message passing is easy to implement in Rust (channels in the standard library), while sharing objects is not.



  • @Gąska said in MVVM and Multithreading in C#:

    @cartman82 it'd actually be a cool idea for GitHub to have dedicated Q&A section for projects.

    Wasn't there some talk or mention of them adding discours to handle per-project forum threads?


  • Banned

    @cartman82 I don't really follow GitHub news.



  • @Gąska said in MVVM and Multithreading in C#:

    @cartman82 I don't really follow GitHub news.

    I don't either. I think Atwood or one of his gang tweeted some screenshot or something about this.

    No need to thank me for this accurate and comprehensive information.


  • ♿ (Parody)

    @cartman82 said in MVVM and Multithreading in C#:

    Wasn't there some talk or mention of them adding discours to handle per-project forum threads?

    There is a discourse plugin to pull github issues into discourse:
    https://what.thedailywtf.com/topic/20391/oh-discourse

    Not sure if that's what you were remembering or not, but I think there was something else, too. That could just be my memory playing tricks, though.


Log in to reply