Ссылка на параметр выражения - PullRequest
0 голосов
/ 05 сентября 2018

Я создал менеджер загрузок, но поскольку менеджер загрузок хранит аргументы загрузки, он работает хорошо.

        Downloader downloader = new Downloader();
        downloader.Add(new List<Query>(){
                            new Query(dataset.trans_sprzedaz_pozycje, () => dataset.PobierzTransSprzedazPozycja(downloader.Filter)),
                            new Query(dataset.trans_sprzedaz_rabaty_dodatkowe, () => dataset.PobierzDokumentySprzedazyRabaty(downloader.Filter)),
                            new Query(dataset.trans_sprzedaz_teksty, () => dataset.PobierzDokumentySprzedazyTeksty(downloader.Filter))
                            });

Но в некоторых случаях мне нужны мои запросы для хранения аргументов, поэтому он должен выглядеть следующим образом:

        Downloader downloader = new Downloader();
        downloader.Add(new List<Query>(){
                            new Query(dataset.trans_sprzedaz_pozycje, () => dataset.PobierzTransSprzedazPozycja(query.Filter)),
                            new Query(dataset.trans_sprzedaz_rabaty_dodatkowe, () => dataset.PobierzDokumentySprzedazyRabaty(query.Filter)),
                            new Query(dataset.trans_sprzedaz_teksty, () => dataset.PobierzDokumentySprzedazyTeksty(query.Filter))
                            });

Обратите внимание, что в первом фрагменте кода я использую downloader.Filter, во втором я использую (сфабрикованный) query.Filter

Я знаю, что могу создавать такие конструкции, как:

        var query = new Query(dsSprzedaz.trans_sprzedaz_pozycje);
        query.AddFunc(() => dsSprzedaz.PobierzTransSprzedazPozycja(query.Filter));

Но добавить 20-30 таких запросов было бы ужасно.

Я пробовал растворение так:

            Filter filter;
            new Query(dsSprzedaz.trans_sprzedaz_pozycje,() => dsSprzedaz.PobierzTransSprzedazPozycja(filter), out filter),

но он копирует значение из запроса. Фильтр, а не ссылка.

// EDIT

Вот самый важный код загрузчика:

    private Task Execute()
    {
        var Tasks = new List<Task>(Queries.Count);

        foreach (var query in Queries)
        {
            var task = query.Execute(CancellationToken);
            Tasks.Add(task);
        }

        return Task.WhenAll(Tasks);
    }

    private void CreateFilter(List<long> id_list)
    {
        lock (Data)
        {
            Data.Clear();

            Data.Append("(0");

            foreach (var value in id_list)
                Data.Append("," + value);

            Data.Append(")");
        }
    }

    public string Filter
    {
        get
        {
            return Data.ToString();
        }
    }

И запрос:

public class Query
{
    DataTable Source;
    Func<DataTable> Download;
    StringBuilder Data;

    public Query(DataTable Source, Expression<Func<DataTable>> Download, out string filter)
    {
        this.Source = Source;
        this.Data = new StringBuilder();

        filter = Filter;
        this.Download = Download.Compile();
    }

    public async Task Execute(CancellationToken cancellationToken)
    {
        try
        {
            DataTable result = await Task.Run(() => Download());

            if (cancellationToken.IsCancellationRequested) return;

            Source.Merge(result);
        }
        catch (Exception) { }
    }

    private void CreateFilter(List<long> id_list)
    {
        lock (Data)
        {
            Data.Clear();

            Data.Append("(0");

            foreach (var value in id_list)
                Data.Append("," + value);

            Data.Append(")");
        }
    }

    public string Filter
    {
        get
        {
            return Data.ToString();
        }
    }
}

`

1 Ответ

0 голосов
/ 05 сентября 2018
  1. Заставьте Query хранить информацию, если он должен использовать свой собственный фильтр (вы сказали, что хотите использовать его только несколько раз, в других случаях вы хотите использовать Downloader.Filter)

    public class Query
    {
        DataTable Source;
        Func<string, DataTable> Download;
        StringBuilder Data;
        public bool IsOwnFilter { get; set; }
    
        public Query(DataTable Source, Func<string, DataTable> Download, bool isOwnFilter = false)
        {
            this.Source = Source;
            this.Data = new StringBuilder();
            this.Download = Download;
            this.IsOwnFilter = isOwnFilter;
        }
    
        public async Task Execute(strign filter, CancellationToken cancellationToken)
        {
            try
            {
                DataTable result = await Task.Run(() => Download(filter));
                if (cancellationToken.IsCancellationRequested) return;
                Source.Merge(result);
            }
            catch (Exception) { }
        }
        // This is not used in your code
        private void CreateFilter(List<long> id_list)
        {
            lock (Data)
            {
                Data.Clear();
                Data.Append("(0");
                foreach (var value in id_list)
                    Data.Append("," + value);
    
                Data.Append(")");
            }
        }
    
        public string Filter
        {
            get
            {
                return Data.ToString();
            }
        }
    }
    
  2. Далее, когда вы вызываете его из Downloader, проверьте наличие нового флага и передайте правильный фильтр:

    private Task Execute()
    {
        var Tasks = new List<Task>(Queries.Count);
    
        foreach (var query in Queries)
        {
            // call Execute with Query filter or Downloader.Filter
            var task = query.Execute(query.IsOwnFilter ? query.Filter : Filter, CancellationToken);
            Tasks.Add(task);
        }
    
        return Task.WhenAll(Tasks);
    }
    

А когда вы добавляете запросы в Downloader:

Downloader downloader = new Downloader();
        downloader.Add(new List<Query>(){
                            new Query(dataset.trans_sprzedaz_pozycje, (filter) => dataset.PobierzTransSprzedazPozycja(filter)),
                            new Query(dataset.trans_sprzedaz_rabaty_dodatkowe, (filter) => dataset.PobierzDokumentySprzedazyRabaty(filter)),
                            new Query(dataset.trans_sprzedaz_teksty, (filter) => dataset.PobierzDokumentySprzedazyTeksty(filter))
                            });
...