-2

I want to run a task which queries a database for new messages for a user. I want the task to run every x seconds, in a new tread so it doesn't cause the UI to become unresponsive.
If the database task finds messages then i would want it to make these messages available to the UI.

I thought the whole loop would run in its own thread, rather than have a loop in the UI thread that keeps creating a new thread every x seconds. I thought that would stop multiple calls to the database e.g. if i set the lookup to every 5 seconds and the database took longer than 5 seconds to respond. I've been looking for a good few hours - the best article i found was: https://blogs.msdn.microsoft.com/benwilli/2016/06/30/asynchronous-infinite-loops-instead-of-timers/

I'm new to threading and the above link seems relatively simple in its last example DoWorkAsyncInfiniteLoop, however it seems to run on the UI thread (although it mentions you could then use Task.Run to make it run in its own thread, and i'm not sure how found messages would be available to the UI thread.

Any advice would be greatly appreciated!

Dave P
  • 13
  • 7
  • 1
    What have you tried? Where's your code? – Jaskier Oct 03 '18 at 21:26
  • As above i've looked into various options before i've cut any code. Think i'm going to go with the infinite loop on separate thread and dispatcher to get the results back. – Dave P Oct 04 '18 at 18:03

2 Answers2

0

Using SQLDependency you will no more need to add an infinite loop. see below link:

SQLDependency Using C#

by using a new thread in WindowsForm you cant directly access to UI Elements because they are in your main thread. in this Situation you must use Dispatchers, here is an explanation about it:

Access UI Element From Another Thread

RezaNoei
  • 1,266
  • 1
  • 8
  • 24
  • Looks good - i'm using oracle, but will look for an equivalent. I think i'm understanding the Dispatcher now, so i think i'm going to go with running the infinite loop and using a dispatcher to get the results back. – Dave P Oct 04 '18 at 18:02
0

OK had some minor difficulty - can't use a dispatcher as i am using MVVM and the view model doesn't have a dispatcher as it is not a derived from a UI base. Here is my final code for anyone else trying to achieve this

 public MainViewModel()  //the constructor for the viewmodel
    {
        _Repo = CurrentApp.MainController.RepositoryManager; // this is my database access methods

        Task t = Task.Run(CheckMessagesAsyncInfiniteLoop);  //run the new thread
    }


    private async Task CheckMessagesAsyncInfiniteLoop()  //this is my infinite loop as described in the above link, but run from the above Task.Run
    {
        while (true)
        {
            // Check the messages in the database
             Messages = _Repo.Service_Message_GetList(CurrentApp.CurrentUser.BasicInfo.UserID);

            // pause for the next check
            await Task.Delay(30000);
        }
    }

    Repository.DomainLayer.MessageCollection _Messages;  //the collection that will be updated by the thread above
    public Repository.DomainLayer.MessageCollection Messages  //the property that my view is bound to
    {
        get
        {
            return _Messages;
        }
        set
        {
            _Messages = value;
            NotifyPropertyChanged();
        }
    }
Dave P
  • 13
  • 7