Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于执行大规模并行查询的泛型类。反馈_C#_Azure_Azure Storage_Azure Table Storage - Fatal编程技术网

C# 用于执行大规模并行查询的泛型类。反馈

C# 用于执行大规模并行查询的泛型类。反馈,c#,azure,azure-storage,azure-table-storage,C#,Azure,Azure Storage,Azure Table Storage,我不明白为什么,但在客户端库中似乎没有机制来并行执行许多针对Windows Azure表存储的查询。我创建了一个模板类,可以用来节省大量的时间,欢迎您随意使用它。不过,如果你能把它分开,并就如何改进这门课提供反馈,我将不胜感激 public class AsyncDataQuery<T> where T: new() { public AsyncDataQuery(bool preserve_order) { m_preserve_order = pr

我不明白为什么,但在客户端库中似乎没有机制来并行执行许多针对Windows Azure表存储的查询。我创建了一个模板类,可以用来节省大量的时间,欢迎您随意使用它。不过,如果你能把它分开,并就如何改进这门课提供反馈,我将不胜感激

public class AsyncDataQuery<T> where T: new()
{
    public AsyncDataQuery(bool preserve_order)
    {
        m_preserve_order = preserve_order;
        this.Queries = new List<CloudTableQuery<T>>(1000);
    }

    public void AddQuery(IQueryable<T> query)
    {
        var data_query = (DataServiceQuery<T>)query;
        var uri = data_query.RequestUri; // required

        this.Queries.Add(new CloudTableQuery<T>(data_query));
    }

    /// <summary>
    /// Blocking but still optimized.
    /// </summary>
    public List<T> Execute()
    {
        this.BeginAsync();
        return this.EndAsync();
    }

    public void BeginAsync()
    {
        if (m_preserve_order == true)
        {
            this.Items = new List<T>(Queries.Count);
            for (var i = 0; i < Queries.Count; i++)
            {
                this.Items.Add(new T());
            }
        }
        else
        {
            this.Items = new List<T>(Queries.Count * 2);
        }

        m_wait = new ManualResetEvent(false);

        for (var i = 0; i < Queries.Count; i++)
        {
            var query = Queries[i];
            query.BeginExecuteSegmented(callback, i);
        }
    }

    public List<T> EndAsync()
    {
        m_wait.WaitOne();
        m_wait.Dispose();

        return this.Items;
    }

    private List<T> Items { get; set; }
    private List<CloudTableQuery<T>> Queries { get; set; }

    private bool m_preserve_order;
    private ManualResetEvent m_wait;
    private int m_completed = 0;
    private object m_lock = new object();

    private void callback(IAsyncResult ar)
    {
        int i = (int)ar.AsyncState;
        CloudTableQuery<T> query = Queries[i];
        var response = query.EndExecuteSegmented(ar);
        if (m_preserve_order == true)
        { // preserve ordering only supports one result per query
            lock (m_lock)
            {
                this.Items[i] = response.Results.Single();
            }
        }
        else
        { // add any number of items
            lock (m_lock)
            {
                this.Items.AddRange(response.Results);
            }
        }
        if (response.HasMoreResults == true)
        { // more data to pull
            query.BeginExecuteSegmented(response.ContinuationToken, callback, i);
            return;
        }
        m_completed = Interlocked.Increment(ref m_completed);
        if (m_completed == Queries.Count)
        {
            m_wait.Set();
        }
    }
}
公共类AsyncDataQuery,其中T:new()
{
公共异步数据查询(布尔保留顺序)
{
m_preserve_order=preserve_order;
this.querys=新列表(1000);
}
公共void AddQuery(IQueryable查询)
{
var data_query=(DataServiceQuery)查询;
var uri=data\u query.RequestUri;//必需
this.querys.Add(newcloudtablequery(data_query));
}
/// 
///阻塞,但仍然优化。
/// 
公共列表执行()
{
this.BeginAsync();
返回这个.EndAsync();
}
public void BeginAsync()
{
if(m_preserve_order==true)
{
this.Items=新列表(querys.Count);
对于(var i=0;i
您是否考虑过使用任务并行库


我想我参加聚会迟到了。我想补充两点:

  • ManualResetEvent可识别。所以你需要确保它在某个地方得到处理
  • 错误处理-如果其中一个查询失败,那么整个查询可能都会失败。您可能应该重试失败的请求。或者,您可以返回返回的值,并指示哪些查询失败,以便调用方可以重试查询
  • 客户端超时-没有超时。如果服务器端超时,这不是问题,但是如果超时失败(例如,网络问题),客户端将永远挂起 另外,我认为这实际上是一种比任务并行库更好的方法。在此之前,我尝试了每查询一个任务的方法。这段代码实际上更加笨拙,而且往往会导致有很多活动线程。我还没有对您的代码进行全面的测试,但乍一看它似乎效果更好

    更新
    我或多或少地重写了上面的代码。“我的重写”删除了所有锁定,支持挂起事务的客户端超时(虽然很少见,但确实会发生,而且会毁了你的一天),以及一些异常处理逻辑。有一个完整的解决方案,可以进行测试。最相关的代码存在于中,尽管它确实需要项目其他部分中的一些助手

    顺便说一句,这是在生产中运行的(在newscandy.com上),到目前为止,它似乎对我的使用效果很好。但似乎还有很大的改进空间。简单看一下:不要公开集合的setter,也不要公开具体的集合实现。好建议。我同意实施也需要更多的考虑。功能方面有什么改进吗?无论是为了性能还是功能。回调是否在多个线程中被调用?我看起来不太安全。特别是
    Items.AddRange
    调用。当您的代码因为有多个结果而无法保持顺序时,应该抛出异常。您可以使用
    .Single
    而不是
    。首先
    这听起来应该放在codereview.stackexchange.com上,而不是放在这里?建议不错。我不确定在这一点上它会给我带来多少好处,但如果我是从零开始,我可能会尝试这条路线。对于那些对多线程开发不太熟悉的人,我当然会推荐任务并行库。很抱歉反应太晚,我不确定我怎么会错过它。很好的反馈。我在ManualResetEvent上添加了manual Dispose调用,但最终它在GC调用析构函数时被销毁。手动调用Dispose实际上只是在(非常)高容量下的一个问题。错误处理是另一个很好的建议,但是现在没有时间调试它(因为我没有使用它)。尽管如此,请随时回复,我会很高兴地更新模板!