ASP.NET页面中的异步C#方法调用用于调试,但不用于实时站点

ASP.NET页面中的异步C#方法调用用于调试,但不用于实时站点,c#,asp.net,asynchronous,sparklines,C#,Asp.net,Asynchronous,Sparklines,好的,情况如下: 我有一个web应用程序,其中有一个关于我们销售人员客户的统计表,每行都有一个迷你图,显示了过去12个月销售数据的总体趋势。每页显示一个特定销售人员的客户列表,其中一些可能有大量的客户=大量的行=大量的火花线(例如,其中一个有125个,需要15秒才能加载) 由于这个原因,无法使用-它们完全固定了用户的CPU,该用户使用IE访问带有大量火花线的页面 因此,我转而使用,它的效果要好得多,除了两个问题:1)它位于一个安全的站点上,而Google Chart API URL仅通过HTTP

好的,情况如下:

我有一个web应用程序,其中有一个关于我们销售人员客户的统计表,每行都有一个迷你图,显示了过去12个月销售数据的总体趋势。每页显示一个特定销售人员的客户列表,其中一些可能有大量的客户=大量的行=大量的火花线(例如,其中一个有125个,需要15秒才能加载)

由于这个原因,无法使用-它们完全固定了用户的CPU,该用户使用IE访问带有大量火花线的页面

因此,我转而使用,它的效果要好得多,除了两个问题:1)它位于一个安全的站点上,而Google Chart API URL仅通过HTTP提供(通过使用一个小包装器脚本动态下载图形并从我们的安全服务器重新提供来解决);2)在一个有125个小图标的页面上,由于请求的数量(即使使用0-9个服务器前缀来最大化可用连接的数量),仍然非常慢

因此,我的下一步是尝试使每个“下载/抓取/重新服务映像”方法调用都是异步的——而且它成功了

…但仅限于在调试模式下运行的我的dev box上

当我把它推到现场时,速度更快了,但它让一些图片被卸载,这当然是不可接受的

这就是我所希望的,一些非常出色的人会知道的:

1) 为什么我的异步方法调用在调试时工作,但在实时站点上不工作

2) 有没有更简单的方法可以在安全的服务器上快速加载大量的火花线,而不让我感到毛骨悚然

2a.)有人有使用ASP.NET图表库的经验吗?这是我应该调查的吗

2b.)一位同事建议我使用1x1 CSS背景图像,并改变高度,制作自己的闪影程序。问题是a)如果我们想要进行更改,它是完全不可扩展的;b) 它看起来像地狱一样骇人听闻(在标记中,每一个小火花都会留下大约一百万个div);c)我不知道当一页上有100-200个这样的页面时,它是否足够快-您对1x1 sprite方法的可行性有何想法


提前感谢。

以我的经验,ASP.Net图表运行良好。有一个快速入门,让你开始与必要的配置,以呈现一个火花

编辑:添加了在MVC中使用ASP.Net图表的示例。很明显,您希望将这些代码中的一部分移动到某种帮助器类中,但希望这能清楚地说明如何才能使这项工作正常进行

    @model IEnumerable<CustomerSales>        
@using Chart = System.Web.UI.DataVisualization.Charting.Chart   
@{    
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            Name
        </th>
        <th>
            Sales
        </th>
    </tr>

@foreach (var item in Model)
{
    <tr>
        <td>
            @item.Name
        </td>
        <td>
            @{

    var chart = new Chart();
    chart.ChartAreas.Add(new ChartArea());
    chart.ChartAreas[0].AxisX.LabelStyle.Enabled = false;
    chart.ChartAreas[0].AxisY.LabelStyle.Enabled = false;
    chart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
    chart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
    chart.ChartAreas[0].AxisX.MajorTickMark.Enabled = false;
    chart.ChartAreas[0].AxisY.MajorTickMark.Enabled = false;
    chart.ChartAreas[0].AxisX.LineWidth = 0;
    chart.ChartAreas[0].AxisY.LineWidth = 0;

    chart.Series.Add(new Series());
        // Assign the random number to the chart to create 35 points
    for (int x = 0; x < item.Sales.Length; x++)
    {
        chart.Series[0].Points.AddXY(x, item.Sales[x]);
    }

     // Start hiding both sets of axes, labels, gridlines and tick marks
     chart.ChartAreas[0].AxisX.LabelStyle.Enabled = false;
     chart.ChartAreas[0].AxisY.LabelStyle.Enabled = false;
     chart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
     chart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
     chart.ChartAreas[0].AxisX.MajorTickMark.Enabled = false;
     chart.ChartAreas[0].AxisY.MajorTickMark.Enabled = false;
     chart.ChartAreas[0].AxisX.LineWidth = 0;
     chart.ChartAreas[0].AxisY.LineWidth = 0;

     // Sparklines use the 'Spline' chart type to show a smoother trend with a line chart
     chart.Series[0].ChartType = SeriesChartType.Spline;

     // Since the line is the only thing you see on the chart, you might want to
     // increase its width.&nbsp; Interestingly, you need to set the BorderWidth property
     // in order to accomplish that.
     chart.Series[0].BorderWidth = 2;

     // Re-adjust the size of the chart to reduce unnecessary white space
     chart.Width = 400;
     chart.Height = 100;
     string base64;
     using (MemoryStream ms = new MemoryStream())
     {
         chart.SaveImage(ms);
         var bytes = ms.GetBuffer();
         base64 = Convert.ToBase64String(bytes);
     }
 /**
  * Here's a simpler example that would do a regular chart, 
  * rather than a sparkline. No way to make the gridlines and axes go
  * away with this helper that I'm aware of.

    var chart = new Chart(
        width: 300,
        height: 100
        )
        .AddSeries(chartType: "Spline", yValues: item.Sales);
    var bytes = chart.GetBytes();
    var base64 = Convert.ToBase64String(bytes);    
             */
                }
             <img src="data:image/jpeg;base64,@base64" />
        </td>
    </tr>
}

</table>

首先,异步并不意味着更快,在您的情况下,如果不进一步降低速度,也不会有什么不同

我只是想简化正在发生的事情,以便我能更好地理解它。有一个页面可以加载125-200个图像。这些图像是动态生成的图形。这是否总结了正在发生的事情?如果是,则:

如果客户端有足够的带宽,服务器可以处理请求,并且服务器上有足够大的管道,那么加载这些图像应该不是问题。那么延迟在哪里呢?是谷歌吗?或者你的服务器正在减慢速度

与直接从浏览器转到谷歌相比,它要慢多少? 从浏览器直接进入谷歌的响应时间可以接受吗? 如果没有,您可能需要在UI中使用不同的策略,以便不会自动加载所有图像。或者每个客户都在一个选项卡中,或者将内容拆分为页面,以便一次只请求少量数据和图像

您使用的Http套接字将被限制为在任何时候向Google发出2个请求,无论您生成了多少个mant线程。有一种方法可以改变这个数字(但我一下子记不起是怎么改变的)。无论如何,这很可能是你减速的原因

使用来自业务层代码的异步调用(如在本例中执行一些I/O绑定操作)并不能使您获得释放请求线程来服务其他请求的好处。为此,您需要使用异步页面,因为该页面可以通知IIS这一事实。任何其他异步工作都只是使用更多的线程(除非您使用的是异步CTP-C#5.0和a中使用的技术,特别是使用I/O线程而不是工作线程)


现在,根据您看到的情况,从Google获取图像时,服务器端存在错误,您需要知道这些错误是什么。我建议您不要为此使用async。

您应该开始研究图像未加载的原因。服务器或javascript中是否有异常?Fireb之类的工具ug for Firefox在这种情况下可以非常方便地跟踪所有请求和服务器响应。图表控件在隔离状态下运行良好,但问题是1)我使用ASP.Net MVC,2)我在动态绘制表,因此我不确定如何(或是否有方法)在视图中的循环中动态生成服务器端控件,我可以在其中粘贴这些图表。(我看到的MVC图表示例使用一个硬编码的面板来粘贴图表,但我事先不知道需要多少面板)-有什么想法吗?很抱歉耽搁了-您当然可以使用MVC中的图表库。这是一个带有这个想法的剃须刀视图的草图。如果您愿意,我可以给您发送一个示例应用程序的zip`@模型IEnumerable Name Sales@foreach(模型中的var项){@item.Name@{var chart=new chart();//etcOK,再试一次:我在注释中没有足够的空间来给出完整的示例,但是您可以只做一个新的字符
public class CustomerSales
{
    public CustomerSales(string name, params int[] sales)
    {
        Name = name;
        Sales = sales;
    }
    [Required]
    public string Name { get; set; }
    [Required]
    public int[] Sales { get; set; }
}