I'm designing a round-based game where one of the core design goals is to have a highly exchangable UI. For this, I've defined an interface which allows implementers to only focus on drawing the UI and processing user input - Everything else happens behind the interface.

The general idea is to have a controller in a background thread/task which calls methods on the interface (synchronously?) which are supposed to block the background thread, while asynchronously playing an animation or waiting for user input. Once the animation finished, or the user pressed/tapped on a button, the background worker shall continue its work.

Solution Strategy

The basic idea is similar to this example:

Main method creates Controller and SampleUI, which both depend on an IUserInterface interface. Controller and SampleUI don't know each other

Note: userInterface is a member of Controller of type IUserInterface. SampleUI implements IUserInterface. The image above is the way this is represented in the Modelio modelling tool.

The intended workflow is like this:

Basically, the UI merely reacts - it does not control anything other than actual drawing.

Technical discussion

The UI will be implemented using C#. It would be preferrable to have a solution which is not specific to Windows Forms, WPF, WebGL or similar.

In a classical example, I would start background work in an async UI method and await a Task. However, since we're having Inversion of Control here, I don't have that option.

What would be the right, modern, C# way of implementing this?

I have found this arcticle from 2009 which would basically recommend a background Thread and calling UI methods through a Synchronization Context. I would have to make sure the background thread does not continue execution while waiting for the UI thread but this should be easily possible.

Is there are safer / more modern way than doing this?

  • Why does inverting control preclude the use of Tasks? – Robert Harvey Apr 24 at 16:11
  • @RobertHarvey The UI shall not know about the existence of Controller and therefore cannot call any methods on the object. Maybe Dependency Inversion would fit better? – Tim Meyer Apr 24 at 16:13
  • OK, but you have an intermediary object in your diagram between the UI and the Controller for decoupling purposes. Surely that can hold a Task? – Robert Harvey Apr 24 at 16:15
  • The intermediary interface is supposed to be a classical interface, i.e. have only pure virtual methods. Feel free to provide an answer which involves an actual object as a matter of communication, though I would prefer if the UI does not even know about the things being done in background at all. – Tim Meyer Apr 24 at 16:18
  • It wouldn't have to. Your UI can still conform to the interface you have provided, and so can the intermediary object. – Robert Harvey Apr 24 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.