powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Async Loading от Стивена Клири
11 сообщений из 111, страница 5 из 5
Async Loading от Стивена Клири
    #39525395
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Алексей КИ так можно. Думаю, что здесь разные способы имеют право на жизнь. :-)
OK
Ищем Минимальный код для Больших таблиц чтобы не тормозило.Мне видится развитие концепции, предложенной ТС.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create table Test
(
    ID int not null primary key,
    Caption varchar(500) not null
)

declare @i int
set @i = 0

set nocount on

while @i < 1000000 begin
    set @i = @i + 1
    insert into Test (ID, Caption) values (@i, '--------------------- Value: ' + cast(@i as varchar) + ' ---------------------------')
end

set nocount off

-- drop table Test


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BackgroundFetch.Properties;

namespace BackgroundFetch
{
    public class DataItem
    {
        public int ID { get; set; }

        public string Caption { get; set; }
    }

    public class DataService
    {
        public async Task LoadData(Action<IEnumerable<DataItem>> appendResult)
        {
            using (var cn = new SqlConnection(Settings.Default.AppDb))
            {
                await cn.OpenAsync();

                using (var cmd = cn.CreateCommand())
                {
                    cmd.CommandTimeout = 300;
                    cmd.CommandText = "select * from Test";

                    using (var rdr = await cmd.ExecuteReaderAsync())
                    {
                        var result = new List<DataItem>();

                        while (await rdr.ReadAsync())
                        {
                            result.Add(new DataItem
                            {
                                ID = Convert.ToInt32(rdr["ID"]),
                                Caption = Convert.ToString(rdr["Caption"])
                            });

                            if (result.Count == 1000)
                            {
                                appendResult(result);
                                result.Clear();
                            }
                        }

                        if (result.Count > 0)
                            appendResult(result);
                    }
                }
            }
        }
    }
}


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BackgroundFetch
{
    public partial class MainWindow : Window
    {
        ObservableCollection<DataItem> Items = new ObservableCollection<DataItem>();

        public MainWindow()
        {
            InitializeComponent();
            dataGrid.ItemsSource = Items;
        }

        async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var svc = new DataService();

            await svc.LoadData(items =>
            {
                foreach (var item in items)
                    Items.Add(item);
            });
        }
    }
}


Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
<Window x:Class="BackgroundFetch.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Grid>
        <DataGrid Margin="10" Name="dataGrid"/>
    </Grid>
</Window>


Записи постепенно добавляются в конец, просмотру таблицы это вроде не мешает.
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525427
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КPetro123OK
Ищем Минимальный код для Больших таблиц чтобы не тормозило.Мне видится развитие концепции, предложенной ТС.
по моему - идеально. Ни убрать, ни добавить.
И страшных слов invoke вроде бы нету).
Спс. за один из методов решения сабжа.
ЗЫ Обилие слов await (старт потока) тут явно из за БД сиквела и дров от этой БД (cmd.ExecuteReaderAsync).
У меня в проекте PosgreSQL (нету XXXXAsync), поэтому вероятно будет 1 поток и одно слово await.
20809489
Ну, и интересен пример с EF. Это ведь прогрессивно).
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525462
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Ну, и интересен пример с EF. Это ведь прогрессивно).
Интересно, как EF справится с PG. Иначе прогрессивность сама себя вывернет наружу (хотя ей не привыкать).
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525467
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныPetro123Ну, и интересен пример с EF. Это ведь прогрессивно).
Интересно, как EF справится с PG. Иначе прогрессивность сама себя вывернет наружу (хотя ей не привыкать).Думаю, что справится. При первой возможности попробую набросать пример.
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525468
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Алексей Кпропущено...
Мне видится развитие концепции, предложенной ТС.
по моему - идеально. Ни убрать, ни добавить.
И страшных слов invoke вроде бы нету).
Спс. за один из методов решения сабжа.
ЗЫ Обилие слов await (старт потока) тут явно из за БД сиквела и дров от этой БД (cmd.ExecuteReaderAsync).
У меня в проекте PosgreSQL (нету XXXXAsync), поэтому вероятно будет 1 поток и одно слово await.
20809489
Ну, и интересен пример с EF. Это ведь прогрессивно).Продолжение, следующее за await, по дефолту выполняется через контекст синхронизации, в глубинах которого живёт Dispatcher.BeginInvoke (аналог PostMessage из winapi). Если контекст синхронизации отсутствует или отключен через .ConfigureAwait(false), то продолжение выполняется через пул потоков.

Базовые СУБД-независимые классы DbCommand и т. п. имеют асинхронные методы, вроде как все современные провайдеры СУБД это так же должны поддерживать. Уточни версию .Net Framework, должен быть 4.5+.

Ну и пример под EF сделаю при первой возможности, самому интересно стало. :-)
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525492
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КБазовые СУБД-независимые классы DbCommand и т. п. имеют асинхронные методы,
тут такая штука:
У меня в своём проекте есть асинхронность не для таблицы, а для добавления слоёв из базы в ГИС карту.
И на строке Task.Run
{
}
создаётся поток в цикле.
Т.е. если поток создаётся, то нафига мне плодить ещё поток на коннект, на command и на реадер?
Код: c#
1.
2.
3.
4.
5.
6.
Task.Run
{
  await XXXX.коннектAsync
  await XXXX.commandAsync
  for (XXXX.readerAsync
}


Масло масляное или оверхед, я так понимаю.
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525494
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныИнтересно, как EF справится с PG
Если PG это Postgre, то ниже описал, что сейчас всё работает если брать непотоковый код к базе и запускать его в потоке.
Не уточнял, потокозащищённый ли сам драйвер к базе.
Пока все ошибки что есть ловятся выше драйвера.
Например, общая коллекция Dictionary меняю на ConcurrentКоллекцию и т.д.
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525540
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныPetro123Ну, и интересен пример с EF. Это ведь прогрессивно).
Интересно, как EF справится с PG. Иначе прогрессивность сама себя вывернет наружу (хотя ей не привыкать).Сразу неправильно понял, что такое PG. :-)

EF с PosgreSQL справляется нормально.
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525543
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123, версия с EF.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BackgroundFetch.Properties;

namespace BackgroundFetch
{
    [Table("Test", Schema = "dbo")]
    public class DataItem
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int ID { get; set; }

        [Required]
        [MaxLength(500)]
        public string Caption { get; set; }
    }

    public class AppDbContext : DbContext
    {
        static AppDbContext()
        {
            Database.SetInitializer<AppDbContext>(null);
        }

        public AppDbContext()
            : base(Settings.Default.AppDb)
        { }

        public IDbSet<DataItem> DataItem
        {
            get { return Set<DataItem>(); }
        }
    }

    public class DataService
    {
        public async Task LoadData(Action<IEnumerable<DataItem>> appendResult)
        {
            using (var db = new AppDbContext())
            {
                var q = db.DataItem.Where(v => v.ID > 10); // <---- Хоть какой-нибудь LINQ запрос.

                using (var e = ((IDbAsyncEnumerable<DataItem>)q).GetAsyncEnumerator())
                {
                    var result = new List<DataItem>();

                    while (await e.MoveNextAsync(CancellationToken.None))
                    {
                        result.Add(e.Current);

                        if (result.Count == 1000)
                        {
                            appendResult(result);
                            result.Clear();
                        }
                    }

                    if (result.Count > 0)
                        appendResult(result);
                }
            }
        }
    }
}

...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525547
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Алексей КБазовые СУБД-независимые классы DbCommand и т. п. имеют асинхронные методы,
тут такая штука:
У меня в своём проекте есть асинхронность не для таблицы, а для добавления слоёв из базы в ГИС карту.
И на строке Task.Run
{
}
создаётся поток в цикле.
Т.е. если поток создаётся, то нафига мне плодить ещё поток на коннект, на command и на реадер?
Код: c#
1.
2.
3.
4.
5.
6.
Task.Run
{
  await XXXX.коннектAsync
  await XXXX.commandAsync
  for (XXXX.readerAsync
}


Масло масляное или оверхед, я так понимаю.При таком использовании Task.Run начало и все продолжения, в том числе в вызываемых методах, выполняются через пул потоков, независимо от наличия контекста синхронизации. Иногда это бывает полезно.
...
Рейтинг: 0 / 0
Async Loading от Стивена Клири
    #39525550
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КTask.Runда.
Думаю, при таком методе берём обычный синхронный код и вставляем не плодя await.
Конечно, смотрим чтобы он был потокобезопасный.
...
Рейтинг: 0 / 0
11 сообщений из 111, страница 5 из 5
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Async Loading от Стивена Клири
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]