异步缓存数据; (开始/结束)的ExecuteReader

时间:2018-01-03 10:01:25

标签: c# sql-server wpf asynchronous caching

我有一个静态方法,我希望在其中缓存我的WPF应用程序运行所需的所有数据。

public static async Task CacheAllAsync() { ... }

现在,为了缓存数据,我在每个模型中都有专门的缓存方法,我需要缓存数据。像这样:

public static void CacheAuthObjects( IAsyncResult result )
{
    SqlCommand cmd = (SqlCommand) result.AsyncState;
    SqlDataReader dbr = cmd.EndExecuteReader( result );

    try
    {
        while ( dbr.Read() )
        {
            CachedData.AuthObjs.Add( new AuthObj( dbr ) );
        }
        dbr.Close();
    }
    catch
    {
        // log; send email to admin...
    }
}

我在我的' CacheAllAsync'中使用了这种方法。像这样的方法:

cmd = new SqlCommand( "SELECT ...." );
cmd.Connection = Engine.CreateDefaultDBConnection();
await cmd.Connection.OpenAsync();
cmd.BeginExecuteReader( AuthObjectDB.CacheAuthObjects, cmd );

我在这里的第一个问题是我不知道手术何时完成。我在网上找到了一些关于使用' BeginExecuteReader'的例子,但他们只会说你需要使用' EndExecuteReader',而不是确切地显示如何。

这里的目标是启动多个BeginExecuteReader(我猜他们大约10或15个)并让他们在完成时告诉我,这样我就可以更新我的GUI最后一个是完整的。所以,请记住,当最后一个专用缓存方法完成时,我需要使用CacheAllAsync方法返回任务。

P.S。 如果你告诉我这不是一个好的方法我会如何改进它,我也将不胜感激。也许将所有这些10-15个分离的线程只放在一个队列中,然后让它们等待对方?我想,这会更慢,但更安全,CPU消耗更少,所以我更喜欢第一种方法。

1 个答案:

答案 0 :(得分:-1)

这只是实现目标的另一种尝试。你对此有何看法?

我把其余的逻辑(连接字符串,命令和打开连接)用于在其专用方法中缓存每个模型列表,如下所示:

public static bool CacheAuthObjects( )
{
    SqlCommand cmd = new SqlCommand( "SELECT ..." );
    cmd.Connection = Engine.CreateDefaultDBConnection();

    cmd.Connection.Open();
    SqlDataReader dbr = cmd.ExecuteReader();

    try
    {
        while ( dbr.Read() )
        {
            CachedData.AuthObjects.Add( new AuthObject( dbr ) );
        }
        dbr.Close();
    }
    catch
    {
        // log, send mail..
        return false;
    }
    finally
    {
        cmd.Connection.Close();
    }
    return true;
}

如您所见,我现在使用ExecuteReader。我正在使用此方法创建Task,将其放入列表中,启动所有任务并等待它们,所有这些都在主缓存方法中,如下所示:

public static async Task<bool> CacheAllAsync()
{
    // creating the list for the tasks
    List<Task<bool>> cachingTasks = new List<Task<bool>>();

    // adding the task
    cachingTasks.Add( new Task<bool>(AuthObjectDB.CacheAuthObjects ) );

    // ... adding the rest of the tasks....

    // starting the tasks
    foreach ( Task t in cachingTasks )
        t.Start();

    // awaiting the tasks to complete
    Task<bool[]> task = Task.WhenAll( cachingTasks );
    await task;

    // checking if any of the tasks failed to complete
    foreach ( bool b in task.Result )
        if ( !b ) return false;

    return true;
}
伊万,你的意思是这样的吗?我更喜欢这个,因为逻辑更均匀地传播。我想如果我要读取主要缓存方法中的数据,你建议ExecuteReader。或者我做错了什么?代码实际上运行良好,UI响应并且正在加载数据。

相关问题