简体   繁体   English

c# 每 x 秒运行一次数据库任务

[英]c# run a database task every x seconds

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.我希望任务每 x 秒运行一次,以新的方式运行,这样就不会导致 UI 变得无响应。
If the database task finds messages then i would want it to make these messages available to the UI.如果数据库任务找到消息,那么我希望它使这些消息可用于 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.我认为整个循环会在它自己的线程中运行,而不是在 UI 线程中有一个循环,每隔 x 秒就会创建一个新线程。 I thought that would stop multiple calls to the database eg if i set the lookup to every 5 seconds and the database took longer than 5 seconds to respond.我认为这会停止对数据库的多次调用,例如,如果我将查找设置为每 5 秒一次并且数据库响应时间超过 5 秒。 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/我一直在寻找几个小时 - 我发现的最好的文章是: 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.我是线程的新手,上面的链接在其最后一个示例 DoWorkAsyncInfiniteLoop 中似乎相对简单,但是它似乎在 UI 线程上运行(尽管它提到您可以使用 Task.Run 使其在自己的线程中运行,并且我不确定如何找到的消息可用于 UI 线程。

Any advice would be greatly appreciated!任何建议将不胜感激!

Using SQLDependency you will no more need to add an infinite loop.使用 SQLDependency,您将不再需要添加无限循环。 see below link:见以下链接:

SQLDependency Using C# 使用 C# 的 SQLDependency

by using a new thread in WindowsForm you cant directly access to UI Elements because they are in your main thread.通过在 WindowsForm 中使用新线程,您无法直接访问 UI 元素,因为它们在您的主线程中。 in this Situation you must use Dispatchers, here is an explanation about it:在这种情况下,你必须使用 Dispatchers,这里有一个关于它的解释:

Access UI Element From Another Thread 从另一个线程访问 UI 元素

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.好的,有一些小困难 - 不能使用调度程序,因为我正在使用 MVVM 并且视图模型没有调度程序,因为它不是从 UI 基础派生的。 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();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM