Большая задержка при вызове WCF-сервиса из silverlight - PullRequest
0 голосов
/ 24 августа 2009

У меня есть приложение silverlight 3, которое извлекает некоторые простые данные из ms-sql-server 2008 через WCF. Сначала он получает все идентификаторы (~ 2000), которые хранятся в базе данных, а затем впоследствии получает все детали этих идентификаторов из другой таблицы (в среднем ~ 10 записей на идентификатор).

Моя проблема в том, что от вызова деталей до получения результатов уходит очень много времени (~ 13-18 секунд). После получения первого элемента данных все остальное приходит быстро.

Где мне искать горлышко бутылки?

Вот код, который я использую. Сначала два моих WCF-метода

Этот получает идентификаторы

    public HashSet<int> GetAllIds()
    {
        HashSet<int> resultSet = new HashSet<int>();
        SqlConnection connection = new SqlConnection(sqlConnectionString);
        connection.Open();

        try
        {
            SqlCommand command = new SqlCommand("SELECT id FROM stammDaten", connection);

            using (IDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    resultSet.Add(reader.GetInt32(0));
                }
                reader.Close();
            }
        }
        catch (Exception e)
        {
            Logger.instance.ErrorRoutine(e, "");
        }

        connection.Close();

        return resultSet;
    }

Этот получает детали для одиночных идентификаторов:

    public List<GeoKoordinates> GetGeoKoordinatesById(int stammDatenId)
    {
        List<GeoKoordinates> resultSet = new List<GeoKoordinates>();
        SqlConnection connection = new SqlConnection(sqlConnectionString);
        connection.Open();

        try
        {
            SqlCommand command = new SqlCommand("SELECT stammDatenId, position, latitude, longitude FROM geoKoordinates WHERE stammDatenId=@stammDatenId ORDER BY stammDatenId, position", connection);
            command.Parameters.Add(new SqlParameter("@stammDatenId", SqlDbType.Int));
            command.Parameters["@stammDatenId"].Value = stammDatenId;

            using (IDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    GeoKoordinates geoKoors = new GeoKoordinates();
                    geoKoors.stammDatenId = reader.GetInt32(0);
                    geoKoors.position = reader.GetInt32(1);
                    geoKoors.latitude = reader.GetDouble(2);
                    geoKoors.longitude = reader.GetDouble(3);

                    resultSet.Add(geoKoors);
                }
                reader.Close();
            }
        }
        catch (Exception e)
        {
            Logger.instance.ErrorRoutine(e, "");
        }

        connection.Close();

        return resultSet;
    }

А вот и функции моего приложения silverlight, которые используют эти методы. _s1 является экземпляром ServiceReference для моего WCF-приложения

private void InitMap()
{
            ...
        _s1.GetAllIdsCompleted += new System.EventHandler<OSMDeepEarthExample.ServiceReference1.GetAllIdsCompletedEventArgs>(s1_GetAllIdsCompleted);
    _s1.GetGeoKoordinatesByIdCompleted += new System.EventHandler<GetGeoKoordinatesByIdCompletedEventArgs>(s1_GetGeoKoordinatesByIdCompleted);
    _startTime = DateTime.Now;
    _s1.GetAllIdsAsync();
    }

Этот вызывается, когда wcf-сервис возвращает идентификаторы

    void s1_GetAllIdsCompleted(object sender, OSMDeepEarthExample.ServiceReference1.GetAllIdsCompletedEventArgs e)
{
    TextBlockTest.Text += (DateTime.Now - _startTime).Seconds.ToString();

    foreach (int id in e.Result)
    {
        _s1.GetGeoKoordinatesByIdAsync(id);
    }
}

И, наконец, тот, который обрабатывает возвращенные наборы деталей.

    void s1_GetGeoKoordinatesByIdCompleted(object sender, GetGeoKoordinatesByIdCompletedEventArgs e)
{
    TextBlockTest.Text += (DateTime.Now - _startTime).Seconds.ToString();

    if (e.Result.Count > 0)
    {
        Polygon thePoly = new Polygon();
        _myLayer.Add(thePoly);

        ObservableCollection<Point> myPoints = new ObservableCollection<Point>();

        foreach (GeoKoordinates ko in e.Result)
        {
            Point point = new Point(ko.longitude, ko.latitude);

            if (!myPoints.Contains(point))
                myPoints.Add(point);
        }

        thePoly.Points = myPoints;
                    ... more polygone formatting ...

    }

Заранее спасибо, Frank

1 Ответ

1 голос
/ 06 января 2010

Итак, вот что вы делаете:

Call WCF
Open db connection
get 2000 records
close connection

for 1 to 2000
    Call WCF
    open db connection
    get 10 records
    close connection
next

20 секунд кажется очень быстрым, чтобы сделать 2001 вызов WCF и открыть и закрыть соединение с базой данных 2001 раз.

попробуйте так:

Call WCF once
Open db connection
get 2000 records
for 1 to 2000
    get 10 records
next
close db connection

return a List<GeoKoordinates> 

1 вызов WCF и 1 подключение к базе данных должны быть намного быстрее

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...