在使用Entity Framework等待数据更改时,是否有更好的替代Thread.Sleep?

Pet*_*Luu 4 c# multithreading entity-framework

我有一个使用Entity Framework访问的数据库和一组我需要在远程机器上按顺序执行的操作.机器在完成后通过更新数据库进行通信,否则不报告.鉴于其余代码的体系结构,提供一些我可以加入的事件将是困难的(虽然这将是理想的).我试图做的一个例子是:

private enum Machines
{
    SetA,
    SetB
};

private void Action()
{
    ExecuteWork(Machines.SetA);
    while (!IsWorkDone(Machines.SetA))
    {
        Thread.Sleep(TimeSpan.FromMinutes(1));
    }
    ExecuteWork(Machines.SetB);
}

private void ExecuteWork(Machines machineGroup)
{
    // Do long running work on every remote machine in this set, between 10-40 minutes.
    // When this work is completed, each machine reports its completion to a database.
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法阻止执行下一个操作,直到第一个操作完成,如果限制是我们必须依赖数据库进行状态更新?

private bool IsWorkDone(Machines machineGroup)
{
    using (_context = new DbContext())
    {
        var machines = _context.Machines.Where(machine => machine.Group.Equals(machineGroup.ToString(), StringComparison.OrdinalIgnoreCase));
        foreach (var machine in machines)
        {
            if (machine.Status == Status.Incomplete)
            {
                return false;
            }
        }
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jac*_*ert 5

我会建议使用async,awaitTask这一点.没有太多工作,您可以将您的Action()功能更改为:

private async Task Action()
{
    ExecuteWork(Machines.SetA);
    while (!IsWorkDone(Machines.SetA))
    {
        await Task.Delay(TimeSpan.FromMinutes(1));
    }
    ExecuteWork(Machines.SetB);
}

虽然这仍然等待ExecuteWork()完成,但它是以非阻塞方式完成的.因此,调用的代码Action()将如下所示:

//does not have to be async
private async Task Test()
{
    //Action will execute until it hits the await Task.Delay(),
    //at which point, execution will return to this function
    //(if Test() is marked async) until the time span is up.
    Task t = Action();
    //If Test() is not async, I believe that Action() will run
    //on a separate thread, but I may be wrong.

    for(int i = 0; i < 100; i++){
        console.log(i);
    }

    //At this point, execution of Test() will stop until
    //Action() finnishes, and the calling function will continue if it 
    //has the async modifier.
    await t;
}
Run Code Online (Sandbox Code Playgroud)

如果没有标记该功能async Task,但只是void,您将等待t完成使用t.Wait().