{"id":330105,"date":"2022-02-25T09:00:31","date_gmt":"2022-02-25T09:00:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=330105"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=330105","title":{"rendered":"<span>\u041a\u0430\u043a \u043d\u0435 \u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0437\u0430\u0441\u043d\u0443\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote>\n<p>\u041e\u0434\u043d\u043e \u0438\u0437 \u0434\u0432\u0443\u0445, \u2014 \u043f\u0440\u043e\u0448\u0435\u043b\u0435\u0441\u0442\u0435\u043b \u043e\u043d, \u2014 \u0438\u043b\u0438 \u043f\u0430\u0446\u0438\u0435\u043d\u0442 \u0436\u0438\u0432, \u0438\u043b\u0438 \u043e\u043d \u0443\u043c\u0435\u0440. \u0415\u0441\u043b\u0438 \u043e\u043d \u0436\u0438\u0432 \u2014 \u043e\u043d \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0436\u0438\u0432 \u0438\u043b\u0438 \u043e\u043d \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0436\u0438\u0432. \u0415\u0441\u043b\u0438 \u043e\u043d \u043c\u0451\u0440\u0442\u0432 \u2014 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0438\u043b\u0438 \u043d\u0435\u043b\u044c\u0437\u044f \u043e\u0436\u0438\u0432\u0438\u0442\u044c.  <\/p>\n<p>\u0410.\u041d. \u0422\u043e\u043b\u0441\u0442\u043e\u0439. &#171;\u0417\u043e\u043b\u043e\u0442\u043e\u0439 \u043a\u043b\u044e\u0447\u0438\u043a, \u0438\u043b\u0438 \u041f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0411\u0443\u0440\u0430\u0442\u0438\u043d\u043e&#187;<\/p>\n<\/blockquote>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2c9\/166\/c9f\/2c9166c9f2ca45cf93368fc6ad6ff308.png\" width=\"778\" height=\"529\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2c9\/166\/c9f\/2c9166c9f2ca45cf93368fc6ad6ff308.png\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0432 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438, \u0433\u0434\u0435 \u044f \u0442\u0440\u0443\u0436\u0443\u0441\u044c, \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0438\u0434\u0435\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 20 \u043b\u0435\u0442 \u0438 \u0437\u0430 \u044d\u0442\u043e\u0442 \u0441\u0440\u043e\u043a \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430. \u0415\u0441\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e &#8212; \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043c\u043e\u0440\u0441\u043a\u0438\u0445 \u0433\u0440\u0443\u0437\u043e\u0432\u044b\u0445 \u043f\u0435\u0440\u0435\u0432\u043e\u0437\u043e\u043a \u0438 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0434\u043e\u0432 \u0432 \u043f\u043e\u0440\u0442\u0443. \u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c <abbr title=\"\u041d\u0430\u0443\u0447\u043d\u043e-\u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0438 \u043e\u043f\u044b\u0442\u043d\u043e-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0441\u043a\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b\" type=\"abbr\">\u041d\u0418\u041e\u041a\u0420<\/abbr> \u0438 \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u043a\u0430\u043a \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0438\u0445 \u0440\u0435\u0448\u0430\u0442\u044c. \u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 ASP.NET Core \u043f\u043e\u0434 .NET 6. \u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0440\u0430\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0430\u0441\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u043e \u043c\u0435\u0440\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 \u041f\u041e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 WPF \u043f\u043e\u0434 .NET 6. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0443\u0437\u043a\u043e\u043f\u0440\u043e\u0444\u0438\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u043d\u0430 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445.<\/p>\n<h2>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h2>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043b\u0435\u043d\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u0438\u0445 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e. \u0417\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0447\u0442\u043e-\u0442\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c &#8212; \u043d\u0435\u0433\u0443\u043c\u0430\u043d\u043d\u043e \u0438 \u043f\u043e\u043f\u0430\u0445\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u043e\u043c. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0438\u0434\u0438\u0442 \u0433\u0440\u0443\u0441\u0442\u0438\u0442, \u0440\u0443\u0433\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0434\u0430\u0432\u0438\u0442 \u043d\u0430 \u0442\u0435\u0445\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438\u0434\u0451\u0442 \u043f\u0440\u044f\u043c\u043e \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 <abbr title=\"Borland Database Engine\" type=\"abbr\">BDE<\/abbr>, \u043d\u0438\u0447\u0435\u0433\u043e \u0441 \u044d\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0436\u0435 \u043d\u0435\u043b\u044c\u0437\u044f. \u0412 \u043d\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u0440\u043e \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0448\u043b\u0435\u0442 JSON \u0447\u0435\u0440\u0435\u0437 HTTP. \u0415\u0441\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c &#171;\u0432 \u043b\u043e\u0431&#187;, \u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043c\u0430\u043b\u043e \u0447\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f: \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044f \u0438\u0445 \u0438\u0437 \u0431\u0430\u0437\u044b \u0438\u043b\u0438 \u0435\u0449\u0451 \u043a\u0430\u043a-\u0442\u043e. \u041f\u043e\u0442\u043e\u043c \u0432\u0441\u044e \u044d\u0442\u0443 \u043c\u0430\u0445\u0438\u043d\u0443 \u043e\u043d \u043f\u043e\u0448\u043b\u0451\u0442 \u0432 \u043e\u0442\u0432\u0435\u0442\u043d\u043e\u043c HTTP-\u043f\u0430\u043a\u0435\u0442\u0435, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0435\u0440\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u0432 JSON, \u0442\u0430\u043c \u044d\u0442\u043e \u0432\u0441\u0451 \u0431\u0443\u0434\u0435\u0442 \u0432 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u0441\u0435\u0441\u0442 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u043d\u0443\u0442 \u043f\u0440\u0435\u0434 \u0432\u0437\u043e\u0440\u043e\u043c \u043f\u043e\u0442\u0435\u0440\u044f\u0432\u0448\u0435\u0433\u043e \u043d\u0430\u0434\u0435\u0436\u0434\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. <\/p>\n<h2>\u0418\u0434\u0435\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0410 \u0434\u0430\u0432\u0430\u0439\u0442\u0435, \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0430\u0447\u043d\u0451\u0442 \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u0441\u0432\u043e\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e, \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435, \u043d\u043e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u043d\u0435 \u0432\u0441\u0451, \u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0434\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 \u0438\u043b\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438\u043b\u0438 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0441\u0443\u043f\u0435\u0440\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435, \u0443\u0436\u0435 \u0432\u0441\u0451 \u0438\u043b\u0438 \u043d\u0435\u0442. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0435\u0442, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0435\u0434\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u043e\u0440\u0446\u0438\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0443\u0432\u0438\u0434\u0438\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u0430\u0436\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:<\/p>\n<pre><code class=\"cs\">public enum PartialLoaderState { New, Partial, Full ... }  public interface IPartialLoader&lt;T> { \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435: \u043d\u043e\u0432\u044b\u0439 \u0438\u043b\u0438 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 Chunk (\u043f\u043e\u043b\u043d\u044b\u043c\u0438 \u0438\u043b\u0438      \/\/ \u043d\u0435\u043f\u043e\u043b\u043d\u044b\u043c\u0438)     PartialLoaderState State { get; }     \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445     Task StartAsync(IAsyncEnumerable&lt;T> data, PartialLoaderOptions options);     \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u0440\u0442\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0445     Task ContinueAsync();     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435     List&lt;T> Result { get; }     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u0430\u0440\u0442\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435      \/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 StartAsync() \u0438\u043b\u0438 ContinueAsync()     List&lt;T> Chunk { get; }     ... }  public class PartialLoaderOptions {     \/\/ \u0417\u0430\u0434\u0430\u0451\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442, \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437    \/\/ \u043c\u0435\u0442\u043e\u0434\u043e\u0432 StartAsync() \u0438\u043b\u0438 ContinueAsync()   public TimeSpan Timeout { get; set; } = TimeSpan.FromMilliseconds(-1);     \/\/ \u0417\u0430\u0434\u0430\u0451\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442    \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 StartAsync() \u0438\u043b\u0438 ContinueAsync()     public int Paging { get; set; } = 0;  ... } <\/code><\/pre>\n<p>\u041e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<h2>\u041b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u044b\u0442\u0430\u0442\u044c, \u043a\u0430\u043a \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 VisualStudio Studio Community\u00a02022 \u0442\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0417\u0434\u0435\u0441\u044c \u043e\u043f\u0438\u0448\u0443 \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u0440\u0430\u0442\u043a\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b <a href=\"https:\/\/github.com\/leksiq\/PartialLoader\/tree\/v1.0.0\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442 <\/a>\u0438\u043b\u0438 <a href=\"https:\/\/github.com\/leksiq\/PartialLoader\/releases\/tag\/v1.0.0\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<ul>\n<li>\n<p><code>BigCatsDataContract<\/code> &#8212; \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043e\u0431\u0449\u0438\u0445 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#8212; \u043a\u043e\u0448\u043a\u0443. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cs\">public class Cat {     public string Name { get; set; } }  public class Constants {   public const string PartialLoaderStateHeaderName =        \"X-CatsPartialLoaderState\";   public const string PartialLoaderSessionKey =        \"X-CatsPartialLoaderSessionKey\";   public const string Partial = \"Partial\";   public const string Full = \"Full\"; } <\/code><\/pre>\n<ul>\n<li>\n<p><code>BigCatsDataServer<\/code> &#8212; \u043f\u0440\u043e\u0435\u043a\u0442 ASP.NET Core.  \u0412 <code>Program.cs<\/code> \u041c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u0432\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cs\">\/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c count \u043a\u043e\u0448\u0435\u043a \u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0435\u0439 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 delay,  \/\/ \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0435\u0439\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u0448\u043a\u0438 app.MapGet(\"\/cats\/{count=1001}\/{delay=0}\",     async (HttpContext context, int count, double delay) =>     await Task.Run(() => CatsGenerator.GetCats(context, count, delay)) ); \/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c count \u043a\u043e\u0448\u0435\u043a \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 delay,  \/\/ \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0435\u0439\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u0448\u043a\u0438, \u043f\u0430\u0440\u0442\u0438\u044f\u043c\u0438, \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0445  \/\/ \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c timeout \u0438\u043b\u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u043e\u0439 paging app.MapGet(\"\/catsChunks\/{count=1001}\/{timeout=100}\/{paging=1000}\/{delay=0}\",     async (HttpContext context, int count, int timeout, int paging,             double delay) =>     await Task.Run(() => CatsGenerator.GetCatsChunks(context, count, timeout,                                                       paging, delay)) );<\/code><\/pre>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 <code>CatsGenerator \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u043c\u0435\u0442\u043e\u0434, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u043c\u0435\u0442\u043e\u0434\u044b, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u044b:<\/code><\/p>\n<pre><code class=\"cs\">public class CatsGenerator {     private const string CatNamePrefix = \"\u041a\u043e\u0448\u043a\u0430 \u2116\";    public static async IAsyncEnumerable&lt;Cat> GenerateManyCats(int count,                                                               double delay)     {     ...                        yield return await Task.Run(() =>          {             if (delay > 0)             {                 \/\/ \u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u043b\u0438 \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u043e\u0439 delay, \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u043c \u0431\u0443\u0440\u043d\u0443\u044e                  \/\/ \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e delay \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434.             }             return new Cat { Name = $\"{CatNamePrefix}{i + 1}\" };          });     }      \/\/\/ &lt;summary>     \/\/\/     \u041c\u0435\u0442\u043e\u0434, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0432\u0441\u0435\u0445 \u043a\u043e\u0448\u0435\u043a \u0441\u0440\u0430\u0437\u0443.     \/\/\/ &lt;\/summary>     public static async Task GetCats(HttpContext httpContext, int count,                                        double delay)     {         List&lt;Cat> cats = new();         await foreach(Cat cat in GenerateManyCats(count, delay))         {             cats.Add(cat);         }         await httpContext.Response.WriteAsJsonAsync&lt;List&lt;Cat>>(cats);     }      \/\/\/ &lt;summary>     \/\/\/     \u041c\u0435\u0442\u043e\u0434, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0448\u0435\u043a \u043f\u0430\u0440\u0442\u0438\u044f\u043c\u0438.      \/\/\/ &lt;\/summary>     public static async Task GetCatsChunks(HttpContext context, int count,                                     int timeout, int paging, double delay)     {         IPartialLoader&lt;Cat> partialLoader;         string key = null!;          \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.        \/\/ \u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u043a\u0430\u043a Singleton, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0436\u0438\u0432\u0451\u0442 \u0432\u0435\u0447\u043d\u043e.         CatsLoaderStorage loaderStorage =                context.RequestServices.GetRequiredService&lt;CatsLoaderStorage>();          if (!context.Request.Headers.ContainsKey(           Constants.PartialLoaderSessionKey))         {             \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u043c IPartialLoader (\u0412 \u043d\u0430\u0448\u0435\u043c            \/\/ \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0433\u0434\u0435 \u043e\u043d            \/\/ \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u0430\u043a Transient) \u0438 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e.             partialLoader = context.RequestServices.               GetRequiredService&lt;IPartialLoader&lt;Cat>>();             await partialLoader.StartAsync(GenerateManyCats(count, delay),                                             new PartialLoaderOptions {                  Timeout = TimeSpan.FromMilliseconds(timeout),                 Paging = paging,             });         }          else         {             \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u043b\u044e\u0447 \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430            \/\/ \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0431\u0435\u0440\u0451\u043c PartialLoader \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c            \/\/ \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e.             key = context.Request.Headers[Constants.PartialLoaderSessionKey];             partialLoader = loaderStorage.Data[key];             await partialLoader.ContinueAsync();         }          \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0432\u0435\u0442\u0430, \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0438\u0439, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u044d\u0442\u043e \u043f\u0430\u0440\u0442\u0438\u044f        \/\/ \u0438\u043b\u0438 \u043d\u0435\u0442.         context.Response.Headers.Add(Constants.PartialLoaderStateHeaderName,                                      partialLoader.State.ToString());              if(partialLoader.State == PartialLoaderState.Partial)             {                 \/\/ \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0442\u0438\u044f \u043d\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f,                  if(key is null)                 {                     \/\/ \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0442\u0438\u044f \u043f\u0435\u0440\u0432\u0430\u044f, \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447 \u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c                    \/\/ IPartialLoader \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435.                     key = Guid.NewGuid().ToString();                     loaderStorage.Data[key] = partialLoader;                 }                 \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0432\u0435\u0442\u0430 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c.                 context.Response.Headers.Add(                   Constants.PartialLoaderSessionKey, key);             }             else             {                 \/\/ \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0442\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f, \u0443\u0434\u0430\u043b\u044f\u0435\u043c IPartialLoader \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430.                 if (key is not null)                 {                     loaderStorage.Data.Remove(key);                 }             }               await context.Response.WriteAsJsonAsync&lt;List&lt;Cat>>(               partialLoader.Chunk);         }     } <\/code><\/pre>\n<ul>\n<li>\n<p><code>BigCatsDataClient<\/code> &#8212; \u043f\u0440\u043e\u0435\u043a\u0442 WPF. \u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0430 \u0432 code-behind \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u044b \u043c\u0435\u0442\u043e\u0434\u044b, \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u0448\u0435\u043a \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u0447\u0430\u0441\u0442\u044f\u043c\u0438. \u041a\u043e\u0434 \u0434\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e, \u043e\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cs\">private const string Server = \"https:\/\/localhost:7209\";  \/\/\/ &lt;summary xml:lang=\"ru\"> \/\/\/     \u041c\u0435\u0442\u043e\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \/\/\/ &lt;\/summary> private async Task GetAllCats() {   ...     try     {       ...         using HttpClient _client = new HttpClient();         ...         _client.BaseAddress = new Uri(Server);          \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0432 \u0441\u0442\u0438\u043b\u0435 REST         HttpRequestMessage request = new HttpRequestMessage(           HttpMethod.Get,           $\"{Constants.AllUri}\/{Count}\/{Delay.ToString().Replace(',', '.')}\");         HttpResponseMessage response = await _client.SendAsync(request);          if(response.StatusCode == System.Net.HttpStatusCode.OK)         {             await Dispatcher.BeginInvoke(async () =>             {                 List&lt;Cat>? list = await JsonSerializer.                   DeserializeAsync&lt;List&lt;Cat>>(                   response.Content.ReadAsStream(),                         new JsonSerializerOptions {                            PropertyNameCaseInsensitive = true                            });                     \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u0448\u0435\u043a \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u043a\u043e\u0448\u043a\u0430\u043c\u0438                 foreach (Cat cat in list)                 {                     Cats.Add(cat);                 } ...             });         }       ...      }     catch (Exception ex)     {         \/\/ \u0427\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0442\u0430\u043a       ...     } }  \/\/\/ &lt;summary xml:lang=\"ru\"> \/\/\/     \u041c\u0435\u0442\u043e\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0447\u0430\u0441\u0442\u044f\u043c\u0438. \/\/\/ &lt;\/summary> private async Task GetChunksCats() {   ...     try     {       ...                      using HttpClient _client = new HttpClient();     ...         _client.BaseAddress = new Uri(Server);          \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0432 \u0441\u0442\u0438\u043b\u0435 REST         HttpRequestMessage request = new HttpRequestMessage(           HttpMethod.Get,            $\"{Constants.ChunkslUri}\/{Count}\/{Timeout}\/{Paging}\/{Delay.ToString().Replace(',', '.')}\");         HttpResponseMessage response = await _client.SendAsync(request);     ...         while(response.StatusCode == System.Net.HttpStatusCode.OK               &amp;&amp; IsDataLOading)         {             await Dispatcher.BeginInvoke(async () =>             {                 List&lt;Cat>? list = await JsonSerializer.                   DeserializeAsync&lt;List&lt;Cat>>(                   response.Content.ReadAsStream(),                         new JsonSerializerOptions {                            PropertyNameCaseInsensitive = true });                  \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u0448\u0435\u043a \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u043a\u043e\u0448\u043a\u0430\u043c\u0438                 foreach (Cat cat in list)                 {                     Cats.Add(cat);                 }  ...                                        if (response.Headers.GetValues(                   Constants.PartialLoaderStateHeaderName).First() ==                      Constants.Partial)                 {                     \/\/ \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0448\u043b\u0438 \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e, \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441.                    \/\/ \u041c\u043e\u0436\u043d\u043e \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442                    \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e,                     \/\/ \u043d\u043e \u043e\u043d\u0438 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f,                    \/\/ \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430,                   \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440                     \/\/ \u0432\u0435\u0440\u043d\u0443\u043b \u043d\u0430\u043c \u0441 \u043d\u0435\u043f\u043e\u043b\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.                     request = new HttpRequestMessage(                       HttpMethod.Get, $\"{Constants.ChunkslUri}\");                     request.Headers.Add(                       Constants.PartialLoaderSessionKey,                        response.Headers.GetValues(                         Constants.PartialLoaderSessionKey).First());                     response = await _client.SendAsync(request);                 }                ...             });         }        ...     }     catch (Exception ex)     {        \/\/ \u0427\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0442\u0430\u043a      ...     } } <\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bf8\/1bd\/911\/bf81bd911742f778b3f443c4e65fb270.png\" width=\"992\" height=\"525\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bf8\/1bd\/911\/bf81bd911742f778b3f443c4e65fb270.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0411\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c 100000 \u043a\u043e\u0448\u0435\u043a \u0441 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 0.1 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0436\u043c\u0451\u043c &#171;\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0432\u0441\u0451&#187;.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/502\/a5c\/87a\/502a5c87ae166971259bae99f811b215.png\" width=\"984\" height=\"511\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/502\/a5c\/87a\/502a5c87ae166971259bae99f811b215.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/29f\/895\/822\/29f89582241887edd468195609cc5c42.png\" width=\"979\" height=\"506\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/29f\/895\/822\/29f89582241887edd468195609cc5c42.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0437\u0430 10 \u0441\u0435\u043a\u0443\u043d\u0434 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438. \u0412 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0431\u044b\u043b\u0430 \u043f\u0443\u0441\u0442\u0430 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u0447\u0430\u0441\u0438\u043a\u0430\u043c \u043c\u043e\u0433 \u043d\u0430\u0434\u0435\u044f\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0436\u0438\u0432\u043e\u0435.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044f\u043c\u0438. \u0422\u0430\u0439\u043c\u0430\u0443\u0442 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c 200, \u043c\u0435\u043d\u044c\u0448\u0435 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 <code>PartialLoader<\/code> \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>ManualResetEventSlim.Wait(...)<\/code> \u0438 \u043c\u0435\u043d\u044c\u0448\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u0442\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/054\/fb8\/eb1\/054fb8eb1a971f492cca298bcc95e434.png\" width=\"984\" height=\"511\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/054\/fb8\/eb1\/054fb8eb1a971f492cca298bcc95e434.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/875\/dc5\/f21\/875dc5f21297d4224476bd099dd7e4fe.png\" width=\"983\" height=\"515\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/875\/dc5\/f21\/875dc5f21297d4224476bd099dd7e4fe.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0443\u0436\u0435 \u0447\u0435\u0440\u0435\u0437 \u0434\u0435\u0441\u044f\u0442\u044b\u0435 \u0434\u043e\u043b\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0432\u0438\u0434\u0435\u043b \u043f\u0435\u0440\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. <\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 \u0437\u0430\u0434\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0438. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/528\/fd7\/242\/528fd724218aed7a71db4ae7d61b7040.png\" width=\"982\" height=\"514\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/528\/fd7\/242\/528fd724218aed7a71db4ae7d61b7040.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1a4\/864\/af3\/1a4864af3e74a0db927ac06f9e8dbb60.png\" width=\"975\" height=\"506\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1a4\/864\/af3\/1a4864af3e74a0db927ac06f9e8dbb60.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0432\u0441\u0451 \u043f\u0440\u043e\u0448\u043b\u043e \u043f\u043e \u043f\u043b\u0430\u043d\u0443.<\/p>\n<p>\u041d\u0443 \u0438 \u043e\u0431\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/06b\/27b\/4ee\/06b27b4ee38a94647d9b59ddd792d56c.png\" width=\"981\" height=\"518\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/06b\/27b\/4ee\/06b27b4ee38a94647d9b59ddd792d56c.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/aef\/a1f\/752\/aefa1f75269b7974aa8d472bb1395f7d.png\" width=\"977\" height=\"505\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/aef\/a1f\/752\/aefa1f75269b7974aa8d472bb1395f7d.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0438 \u0442\u0430\u043a\u043e\u0439, \u0447\u0442\u043e <code>timeout<\/code> \u0438 <code>paging<\/code> \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043f\u043e\u0440\u043e\u0432\u043d\u0443 &#8212; 51% \u0432 \u043f\u043e\u043b\u044c\u0437\u0443 <code>paging<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p>1<\/p>\n<\/td>\n<td>\n<p>1803<\/p>\n<\/td>\n<td>\n<p>00:00:00.1110889<\/p>\n<\/td>\n<td>\n<p>1803<\/p>\n<\/td>\n<td>\n<p>00:00:00.1110889<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>2<\/p>\n<\/td>\n<td>\n<p>1971<\/p>\n<\/td>\n<td>\n<p>00:00:00.2389203<\/p>\n<\/td>\n<td>\n<p>3774<\/p>\n<\/td>\n<td>\n<p>00:00:00.3500092<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>3<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2179351<\/p>\n<\/td>\n<td>\n<p>5844<\/p>\n<\/td>\n<td>\n<p>00:00:00.5679443<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>4<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2198922<\/p>\n<\/td>\n<td>\n<p>7914<\/p>\n<\/td>\n<td>\n<p>00:00:00.7878365<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>5<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2197443<\/p>\n<\/td>\n<td>\n<p>9984<\/p>\n<\/td>\n<td>\n<p>00:00:01.0075808<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>6<\/p>\n<\/td>\n<td>\n<p>2061<\/p>\n<\/td>\n<td>\n<p>00:00:00.2236320<\/p>\n<\/td>\n<td>\n<p>12045<\/p>\n<\/td>\n<td>\n<p>00:00:01.2312128<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>7<\/p>\n<\/td>\n<td>\n<p>2055<\/p>\n<\/td>\n<td>\n<p>00:00:00.2192046<\/p>\n<\/td>\n<td>\n<p>14100<\/p>\n<\/td>\n<td>\n<p>00:00:01.4504174<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>8<\/p>\n<\/td>\n<td>\n<p>2026<\/p>\n<\/td>\n<td>\n<p>00:00:00.2243919<\/p>\n<\/td>\n<td>\n<p>16126<\/p>\n<\/td>\n<td>\n<p>00:00:01.6748093<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>9<\/p>\n<\/td>\n<td>\n<p>2038<\/p>\n<\/td>\n<td>\n<p>00:00:00.2201484<\/p>\n<\/td>\n<td>\n<p>18164<\/p>\n<\/td>\n<td>\n<p>00:00:01.8949577<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>10<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2219114<\/p>\n<\/td>\n<td>\n<p>20234<\/p>\n<\/td>\n<td>\n<p>00:00:02.1168691<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>11<\/p>\n<\/td>\n<td>\n<p>2046<\/p>\n<\/td>\n<td>\n<p>00:00:00.2223356<\/p>\n<\/td>\n<td>\n<p>22280<\/p>\n<\/td>\n<td>\n<p>00:00:02.3392047<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>12<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2228286<\/p>\n<\/td>\n<td>\n<p>24350<\/p>\n<\/td>\n<td>\n<p>00:00:02.5620333<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>13<\/p>\n<\/td>\n<td>\n<p>2025<\/p>\n<\/td>\n<td>\n<p>00:00:00.2215145<\/p>\n<\/td>\n<td>\n<p>26375<\/p>\n<\/td>\n<td>\n<p>00:00:02.7835478<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>14<\/p>\n<\/td>\n<td>\n<p>2048<\/p>\n<\/td>\n<td>\n<p>00:00:00.2218749<\/p>\n<\/td>\n<td>\n<p>28423<\/p>\n<\/td>\n<td>\n<p>00:00:03.0054227<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>15<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2216480<\/p>\n<\/td>\n<td>\n<p>30493<\/p>\n<\/td>\n<td>\n<p>00:00:03.2270707<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>16<\/p>\n<\/td>\n<td>\n<p>2069<\/p>\n<\/td>\n<td>\n<p>00:00:00.2219907<\/p>\n<\/td>\n<td>\n<p>32562<\/p>\n<\/td>\n<td>\n<p>00:00:03.4490614<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>17<\/p>\n<\/td>\n<td>\n<p>2069<\/p>\n<\/td>\n<td>\n<p>00:00:00.2219315<\/p>\n<\/td>\n<td>\n<p>34631<\/p>\n<\/td>\n<td>\n<p>00:00:03.6709929<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>18<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2228502<\/p>\n<\/td>\n<td>\n<p>36701<\/p>\n<\/td>\n<td>\n<p>00:00:03.8938431<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>19<\/p>\n<\/td>\n<td>\n<p>2065<\/p>\n<\/td>\n<td>\n<p>00:00:00.2218863<\/p>\n<\/td>\n<td>\n<p>38766<\/p>\n<\/td>\n<td>\n<p>00:00:04.1157294<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>20<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2228646<\/p>\n<\/td>\n<td>\n<p>40836<\/p>\n<\/td>\n<td>\n<p>00:00:04.3385940<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>21<\/p>\n<\/td>\n<td>\n<p>2067<\/p>\n<\/td>\n<td>\n<p>00:00:00.2219197<\/p>\n<\/td>\n<td>\n<p>42903<\/p>\n<\/td>\n<td>\n<p>00:00:04.5605137<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>22<\/p>\n<\/td>\n<td>\n<p>2069<\/p>\n<\/td>\n<td>\n<p>00:00:00.2212811<\/p>\n<\/td>\n<td>\n<p>44972<\/p>\n<\/td>\n<td>\n<p>00:00:04.7817948<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>23<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2211251<\/p>\n<\/td>\n<td>\n<p>47042<\/p>\n<\/td>\n<td>\n<p>00:00:05.0029199<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>24<\/p>\n<\/td>\n<td>\n<p>2028<\/p>\n<\/td>\n<td>\n<p>00:00:00.2230665<\/p>\n<\/td>\n<td>\n<p>49070<\/p>\n<\/td>\n<td>\n<p>00:00:05.2259864<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>25<\/p>\n<\/td>\n<td>\n<p>2057<\/p>\n<\/td>\n<td>\n<p>00:00:00.2223452<\/p>\n<\/td>\n<td>\n<p>51127<\/p>\n<\/td>\n<td>\n<p>00:00:05.4483316<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>26<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2231241<\/p>\n<\/td>\n<td>\n<p>53197<\/p>\n<\/td>\n<td>\n<p>00:00:05.6714557<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>27<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2201679<\/p>\n<\/td>\n<td>\n<p>55267<\/p>\n<\/td>\n<td>\n<p>00:00:05.8916236<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>28<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2206666<\/p>\n<\/td>\n<td>\n<p>57337<\/p>\n<\/td>\n<td>\n<p>00:00:06.1122902<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>29<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2230042<\/p>\n<\/td>\n<td>\n<p>59407<\/p>\n<\/td>\n<td>\n<p>00:00:06.3352944<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>30<\/p>\n<\/td>\n<td>\n<p>2057<\/p>\n<\/td>\n<td>\n<p>00:00:00.2217751<\/p>\n<\/td>\n<td>\n<p>61464<\/p>\n<\/td>\n<td>\n<p>00:00:06.5570695<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>31<\/p>\n<\/td>\n<td>\n<p>2064<\/p>\n<\/td>\n<td>\n<p>00:00:00.2229603<\/p>\n<\/td>\n<td>\n<p>63528<\/p>\n<\/td>\n<td>\n<p>00:00:06.7800298<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>32<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2216961<\/p>\n<\/td>\n<td>\n<p>65598<\/p>\n<\/td>\n<td>\n<p>00:00:07.0017259<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>33<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2220264<\/p>\n<\/td>\n<td>\n<p>67668<\/p>\n<\/td>\n<td>\n<p>00:00:07.2237523<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>34<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2227823<\/p>\n<\/td>\n<td>\n<p>69738<\/p>\n<\/td>\n<td>\n<p>00:00:07.4465346<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>35<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2218313<\/p>\n<\/td>\n<td>\n<p>71808<\/p>\n<\/td>\n<td>\n<p>00:00:07.6683659<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>36<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2249333<\/p>\n<\/td>\n<td>\n<p>73878<\/p>\n<\/td>\n<td>\n<p>00:00:07.8932992<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>37<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2199873<\/p>\n<\/td>\n<td>\n<p>75948<\/p>\n<\/td>\n<td>\n<p>00:00:08.1132865<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>38<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2228433<\/p>\n<\/td>\n<td>\n<p>78018<\/p>\n<\/td>\n<td>\n<p>00:00:08.3361298<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>39<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.1097573<\/p>\n<\/td>\n<td>\n<p>80088<\/p>\n<\/td>\n<td>\n<p>00:00:08.4458871<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>40<\/p>\n<\/td>\n<td>\n<p>2068<\/p>\n<\/td>\n<td>\n<p>00:00:00.2390979<\/p>\n<\/td>\n<td>\n<p>82156<\/p>\n<\/td>\n<td>\n<p>00:00:08.6849850<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>41<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2215380<\/p>\n<\/td>\n<td>\n<p>84226<\/p>\n<\/td>\n<td>\n<p>00:00:08.9065230<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>42<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2231034<\/p>\n<\/td>\n<td>\n<p>86296<\/p>\n<\/td>\n<td>\n<p>00:00:09.1296264<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>43<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2226903<\/p>\n<\/td>\n<td>\n<p>88366<\/p>\n<\/td>\n<td>\n<p>00:00:09.3523167<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>44<\/p>\n<\/td>\n<td>\n<p>2064<\/p>\n<\/td>\n<td>\n<p>00:00:00.2218493<\/p>\n<\/td>\n<td>\n<p>90430<\/p>\n<\/td>\n<td>\n<p>00:00:09.5741660<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>45<\/p>\n<\/td>\n<td>\n<p>2038<\/p>\n<\/td>\n<td>\n<p>00:00:00.2219079<\/p>\n<\/td>\n<td>\n<p>92468<\/p>\n<\/td>\n<td>\n<p>00:00:09.7960739<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>46<\/p>\n<\/td>\n<td>\n<p>2054<\/p>\n<\/td>\n<td>\n<p>00:00:00.2234104<\/p>\n<\/td>\n<td>\n<p>94522<\/p>\n<\/td>\n<td>\n<p>00:00:10.0194843<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>47<\/p>\n<\/td>\n<td>\n<p>2070<\/p>\n<\/td>\n<td>\n<p>00:00:00.2202597<\/p>\n<\/td>\n<td>\n<p>96592<\/p>\n<\/td>\n<td>\n<p>00:00:10.2397440<\/p>\n<\/td>\n<td>\n<p>1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>48<\/p>\n<\/td>\n<td>\n<p>2048<\/p>\n<\/td>\n<td>\n<p>00:00:00.2221415<\/p>\n<\/td>\n<td>\n<p>98640<\/p>\n<\/td>\n<td>\n<p>00:00:10.4618855<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>49<\/p>\n<\/td>\n<td>\n<p>1360<\/p>\n<\/td>\n<td>\n<p>00:00:00.1118606<\/p>\n<\/td>\n<td>\n<p>100000<\/p>\n<\/td>\n<td>\n<p>00:00:10.5737461<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<p>0,5102040816<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/details>\n<h2>\u041e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 IPartialLoader<\/h2>\n<p>\u041d\u0443 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u043e\u0432 \u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>IPartialLoader<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 <code>StartAsync(...)<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0447\u0438\u0442\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 <code>Enumerable<\/code> \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u041a\u0430\u043a  <code>StartAsync(...)<\/code>, \u0442\u0430\u043a \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>ContinueAsync()<\/code> \u0447\u0438\u0442\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u044d\u0442\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c. \u0414\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043a \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>ManualResetEventSlim<\/code>. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u043e\u043d \u0441\u0431\u0440\u043e\u0448\u0435\u043d. \u041a\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0430\u0447\u0430, \u043f\u0438\u0448\u0443\u0449\u0430\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u043e\u043d\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 <code>ManualResetEventSlim<\/code>, \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0442\u0435\u043d\u0438\u0435 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u041a\u043e\u0433\u0434\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0443\u0441\u0442\u0435\u0435\u0442, <code>ManualResetEventSlim<\/code> \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445.<\/p>\n<pre><code class=\"cs\">public async Task StartAsync(IAsyncEnumerable&lt;T> data, PartialLoaderOptions options) { ...    _manualReset.Reset();          _loadTask = Task.Run(async () => { await foreach (T item in data)   {   if (_cancellationTokenSource.Token.IsCancellationRequested)     {     ...         break;     }     _queue.Enqueue(item);     _manualReset.Set(); } });  ... }    \/\/\/ &lt;summary> \/\/\/     \u041c\u0435\u0442\u043e\u0434, \u043e\u0431\u0449\u0438\u0439 \u0434\u043b\u044f StartAsync(...) \u0438 ContinueAsync(). \/\/\/ &lt;\/summary> private async Task ExecuteAsync() {     DateTimeOffset start = DateTimeOffset.Now;                  while (!_loadTask.IsCompleted)     {         TimeSpan limeLeft = _options.Timeout.TotalMilliseconds &lt; 0 ?             TimeSpan.MaxValue : _options.Timeout - (DateTimeOffset.Now - start);         if (limeLeft == TimeSpan.MaxValue || limeLeft.TotalMilliseconds > 0)         {             try             {                 if (limeLeft == TimeSpan.MaxValue)                 {                     _manualReset.Wait(_cancellationTokenSource!.Token);                 }                 else                 {                     _manualReset.Wait(limeLeft, _cancellationTokenSource!.Token);                 }             }             catch (OperationCanceledException)              {                 await _loadTask;               ...             }             if (_cancellationTokenSource!.Token.IsCancellationRequested)             {                 await _loadTask;               ...                 Output(PartialLoaderState.Canceled);                 return;             }             while (_queue.TryDequeue(out T? item))             {               ...                 _list.Add(item);                 if(_options.Paging > 0                     &amp;&amp; _list.Count - _offset == _options.Paging)                 {                     Output(PartialLoaderState.Partial);                     return;                 }             }         }          else         {             if (_cancellationTokenSource!.Token.IsCancellationRequested)             {                 await _loadTask;               ...                 Output(PartialLoaderState.Canceled);                 return;             }             Output(PartialLoaderState.Partial);             return;         }         if (!_loadTask.IsCompleted)         {             _manualReset.Reset();         }     }     while (_queue.TryDequeue(out T? item))     { ...       _list.Add(item);         if (_options.Paging > 0              &amp;&amp; _list.Count - _offset == _options.Paging)         {             Output(PartialLoaderState.Partial);             return;         }     }     if (_cancellationTokenSource!.Token.IsCancellationRequested)     {       ...         Output(PartialLoaderState.Canceled);         return;     }     if (_loadTask.IsFaulted)     {         throw _loadTask.Exception!;     }     Output(PartialLoaderState.Full); }  private void Output(PartialLoaderState state) {     State = state;     if(State == PartialLoaderState.Partial         || State == PartialLoaderState.Full)     {         _chunk = _list!.GetRange(_offset, _list.Count - _offset);         _offset = _list.Count;     } } <\/code><\/pre>\n<h2>\u0412\u044b\u0432\u043e\u0434<\/h2>\n<p>\u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044f \u0442\u0430\u043a\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0447\u0430\u0441\u0442\u044f\u043c\u0438 \u0438 \u0441\u0440\u0430\u0437\u0443 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044f \u0438\u0445.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/653395\/\"> https:\/\/habr.com\/ru\/post\/653395\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote>\n<p>\u041e\u0434\u043d\u043e \u0438\u0437 \u0434\u0432\u0443\u0445, \u2014 \u043f\u0440\u043e\u0448\u0435\u043b\u0435\u0441\u0442\u0435\u043b \u043e\u043d, \u2014 \u0438\u043b\u0438 \u043f\u0430\u0446\u0438\u0435\u043d\u0442 \u0436\u0438\u0432, \u0438\u043b\u0438 \u043e\u043d \u0443\u043c\u0435\u0440. \u0415\u0441\u043b\u0438 \u043e\u043d \u0436\u0438\u0432 \u2014 \u043e\u043d \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0436\u0438\u0432 \u0438\u043b\u0438 \u043e\u043d \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0436\u0438\u0432. \u0415\u0441\u043b\u0438 \u043e\u043d \u043c\u0451\u0440\u0442\u0432 \u2014 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0438\u043b\u0438 \u043d\u0435\u043b\u044c\u0437\u044f \u043e\u0436\u0438\u0432\u0438\u0442\u044c.  <\/p>\n<p>\u0410.\u041d. \u0422\u043e\u043b\u0441\u0442\u043e\u0439. &#171;\u0417\u043e\u043b\u043e\u0442\u043e\u0439 \u043a\u043b\u044e\u0447\u0438\u043a, \u0438\u043b\u0438 \u041f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0411\u0443\u0440\u0430\u0442\u0438\u043d\u043e&#187;<\/p>\n<\/blockquote>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0432 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438, \u0433\u0434\u0435 \u044f \u0442\u0440\u0443\u0436\u0443\u0441\u044c, \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0438\u0434\u0435\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 20 \u043b\u0435\u0442 \u0438 \u0437\u0430 \u044d\u0442\u043e\u0442 \u0441\u0440\u043e\u043a \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430. \u0415\u0441\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e &#8212; \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043c\u043e\u0440\u0441\u043a\u0438\u0445 \u0433\u0440\u0443\u0437\u043e\u0432\u044b\u0445 \u043f\u0435\u0440\u0435\u0432\u043e\u0437\u043e\u043a \u0438 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0434\u043e\u0432 \u0432 \u043f\u043e\u0440\u0442\u0443. \u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c <abbr title=\"\u041d\u0430\u0443\u0447\u043d\u043e-\u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0438 \u043e\u043f\u044b\u0442\u043d\u043e-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0441\u043a\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b\" type=\"abbr\">\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0441\u043a\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b&#187; type=&#187;abbr&#187;>\u041d\u0418\u041e\u041a<\/abbr> \u0438 \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u043a\u0430\u043a \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0438\u0445 \u0440\u0435\u0448\u0430\u0442\u044c. \u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 ASP.NET Core \u043f\u043e\u0434 .NET 6. \u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0440\u0430\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0430\u0441\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u043e \u043c\u0435\u0440\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 \u041f\u041e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 WPF \u043f\u043e\u0434 .NET 6. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0443\u0437\u043a\u043e\u043f\u0440\u043e\u0444\u0438\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u043d\u0430 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445.<\/p>\n<h2>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h2>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043b\u0435\u043d\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u0438\u0445 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e. \u0417\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0447\u0442\u043e-\u0442\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c &#8212; \u043d\u0435\u0433\u0443\u043c\u0430\u043d\u043d\u043e \u0438 \u043f\u043e\u043f\u0430\u0445\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u043e\u043c. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0438\u0434\u0438\u0442 \u0433\u0440\u0443\u0441\u0442\u0438\u0442, \u0440\u0443\u0433\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0434\u0430\u0432\u0438\u0442 \u043d\u0430 \u0442\u0435\u0445\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438\u0434\u0451\u0442 \u043f\u0440\u044f\u043c\u043e \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 <abbr title=\"Borland Database Engine\" type=\"abbr\">BDE<\/abbr>, \u043d\u0438\u0447\u0435\u0433\u043e \u0441 \u044d\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0436\u0435 \u043d\u0435\u043b\u044c\u0437\u044f. \u0412 \u043d\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u0440\u043e \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0448\u043b\u0435\u0442 JSON \u0447\u0435\u0440\u0435\u0437 HTTP. \u0415\u0441\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c &#171;\u0432 \u043b\u043e\u0431&#187;, \u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043c\u0430\u043b\u043e \u0447\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f: \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044f \u0438\u0445 \u0438\u0437 \u0431\u0430\u0437\u044b \u0438\u043b\u0438 \u0435\u0449\u0451 \u043a\u0430\u043a-\u0442\u043e. \u041f\u043e\u0442\u043e\u043c \u0432\u0441\u044e \u044d\u0442\u0443 \u043c\u0430\u0445\u0438\u043d\u0443 \u043e\u043d \u043f\u043e\u0448\u043b\u0451\u0442 \u0432 \u043e\u0442\u0432\u0435\u0442\u043d\u043e\u043c HTTP-\u043f\u0430\u043a\u0435\u0442\u0435, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0435\u0440\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u0432 JSON, \u0442\u0430\u043c \u044d\u0442\u043e \u0432\u0441\u0451 \u0431\u0443\u0434\u0435\u0442 \u0432 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u0441\u0435\u0441\u0442 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u043d\u0443\u0442 \u043f\u0440\u0435\u0434 \u0432\u0437\u043e\u0440\u043e\u043c \u043f\u043e\u0442\u0435\u0440\u044f\u0432\u0448\u0435\u0433\u043e \u043d\u0430\u0434\u0435\u0436\u0434\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. <\/p>\n<h2>\u0418\u0434\u0435\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0410 \u0434\u0430\u0432\u0430\u0439\u0442\u0435, \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0430\u0447\u043d\u0451\u0442 \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u0441\u0432\u043e\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e, \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435, \u043d\u043e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u043d\u0435 \u0432\u0441\u0451, \u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0434\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 \u0438\u043b\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438\u043b\u0438 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0441\u0443\u043f\u0435\u0440\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435, \u0443\u0436\u0435 \u0432\u0441\u0451 \u0438\u043b\u0438 \u043d\u0435\u0442. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0435\u0442, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0435\u0434\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u043e\u0440\u0446\u0438\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0443\u0432\u0438\u0434\u0438\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u0430\u0436\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:<\/p>\n<pre><code class=\"cs\">public enum PartialLoaderState { New, Partial, Full ... }  public interface IPartialLoader&lt;T> { \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435: \u043d\u043e\u0432\u044b\u0439 \u0438\u043b\u0438 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 Chunk (\u043f\u043e\u043b\u043d\u044b\u043c\u0438 \u0438\u043b\u0438      \/\/ \u043d\u0435\u043f\u043e\u043b\u043d\u044b\u043c\u0438)     PartialLoaderState State { get; }     \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445     Task StartAsync(IAsyncEnumerable&lt;T> data, PartialLoaderOptions options);     \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u0440\u0442\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0445     Task ContinueAsync();     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435     List&lt;T> Result { get; }     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u0430\u0440\u0442\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435      \/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 StartAsync() \u0438\u043b\u0438 ContinueAsync()     List&lt;T> Chunk { get; }     ... }  public class PartialLoaderOptions {     \/\/ \u0417\u0430\u0434\u0430\u0451\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442, \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437    \/\/ \u043c\u0435\u0442\u043e\u0434\u043e\u0432 StartAsync() \u0438\u043b\u0438 ContinueAsync()   public TimeSpan Timeout { get; set; } = TimeSpan.FromMilliseconds(-1);     \/\/ \u0417\u0430\u0434\u0430\u0451\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442    \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 StartAsync() \u0438\u043b\u0438 ContinueAsync()     public int Paging { get; set; } = 0;  ... } <\/code><\/pre>\n<p>\u041e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<h2>\u041b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u044b\u0442\u0430\u0442\u044c, \u043a\u0430\u043a \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 VisualStudio Studio Community\u00a02022 \u0442\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0417\u0434\u0435\u0441\u044c \u043e\u043f\u0438\u0448\u0443 \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u0440\u0430\u0442\u043a\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b <a href=\"https:\/\/github.com\/leksiq\/PartialLoader\/tree\/v1.0.0\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442 <\/a>\u0438\u043b\u0438 <a href=\"https:\/\/github.com\/leksiq\/PartialLoader\/releases\/tag\/v1.0.0\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<ul>\n<li>\n<p><code>BigCatsDataContract<\/code> &#8212; \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043e\u0431\u0449\u0438\u0445 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#8212; \u043a\u043e\u0448\u043a\u0443. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cs\">public class Cat {     public string Name { get; set; } }  public class Constants {   public const string PartialLoaderStateHeaderName =        \"X-CatsPartialLoaderState\";   public const string PartialLoaderSessionKey =        \"X-CatsPartialLoaderSessionKey\";   public const string Partial = \"Partial\";   public const string Full = \"Full\"; } <\/code><\/pre>\n<ul>\n<li>\n<p><code>BigCatsDataServer<\/code> &#8212; \u043f\u0440\u043e\u0435\u043a\u0442 ASP.NET Core.  \u0412 <code>Program.cs<\/code> \u041c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u0432\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cs\">\/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c count \u043a\u043e\u0448\u0435\u043a \u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0435\u0439 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 delay,  \/\/ \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0435\u0439\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u0448\u043a\u0438 app.MapGet(\"\/cats\/{count=1001}\/{delay=0}\",     async (HttpContext context, int count, double delay) =>     await Task.Run(() => CatsGenerator.GetCats(context, count, delay)) ); \/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c count \u043a\u043e\u0448\u0435\u043a \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 delay,  \/\/ \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0435\u0439\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u0448\u043a\u0438, \u043f\u0430\u0440\u0442\u0438\u044f\u043c\u0438, \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0445  \/\/ \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c timeout \u0438\u043b\u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u043e\u0439 paging app.MapGet(\"\/catsChunks\/{count=1001}\/{timeout=100}\/{paging=1000}\/{delay=0}\",     async (HttpContext context, int count, int timeout, int paging,             double delay) =>     await Task.Run(() => CatsGenerator.GetCatsChunks(context, count, timeout,                                                       paging, delay)) );<\/code><\/pre>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 <code>CatsGenerator \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u043c\u0435\u0442\u043e\u0434, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u043c\u0435\u0442\u043e\u0434\u044b, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u044b:<\/code><\/p>\n<pre><code class=\"cs\">public class CatsGenerator {     private const string CatNamePrefix = \"\u041a\u043e\u0448\u043a\u0430 \u2116\";    public static async IAsyncEnumerable&lt;Cat> GenerateManyCats(int count,                                                               double delay)     {     ...                        yield return await Task.Run(() =>          {             if (delay > 0)             {                 \/\/ \u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u043b\u0438 \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u043e\u0439 delay, \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u043c \u0431\u0443\u0440\u043d\u0443\u044e                  \/\/ \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e delay \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434.             }             return new Cat { Name = $\"{CatNamePrefix}{i + 1}\" };          });     }      \/\/\/ &lt;summary>     \/\/\/     \u041c\u0435\u0442\u043e\u0434, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0432\u0441\u0435\u0445 \u043a\u043e\u0448\u0435\u043a \u0441\u0440\u0430\u0437\u0443.     \/\/\/ &lt;\/summary>     public static async Task GetCats(HttpContext httpContext, int count,                                        double delay)     {         List&lt;Cat> cats = new();         await foreach(Cat cat in GenerateManyCats(count, delay))         {             cats.Add(cat);         }         await httpContext.Response.WriteAsJsonAsync&lt;List&lt;Cat>>(cats);     }      \/\/\/ &lt;summary>     \/\/\/     \u041c\u0435\u0442\u043e\u0434, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0448\u0435\u043a \u043f\u0430\u0440\u0442\u0438\u044f\u043c\u0438.      \/\/\/ &lt;\/summary>     public static async Task GetCatsChunks(HttpContext context, int count,                                     int timeout, int paging, double delay)     {         IPartialLoader&lt;Cat> partialLoader;         string key = null!;          \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.        \/\/ \u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u043a\u0430\u043a Singleton, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0436\u0438\u0432\u0451\u0442 \u0432\u0435\u0447\u043d\u043e.         CatsLoaderStorage loaderStorage =                context.RequestServices.GetRequiredService&lt;CatsLoaderStorage>();          if (!context.Request.Headers.ContainsKey(           Constants.PartialLoaderSessionKey))         {             \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u043c IPartialLoader (\u0412 \u043d\u0430\u0448\u0435\u043c            \/\/ \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0433\u0434\u0435 \u043e\u043d            \/\/ \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u0430\u043a Transient) \u0438 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e.             partialLoader = context.RequestServices.               GetRequiredService&lt;IPartialLoader&lt;Cat>>();             await partialLoader.StartAsync(GenerateManyCats(count, delay),                                             new PartialLoaderOptions {                  Timeout = TimeSpan.FromMilliseconds(timeout),                 Paging = paging,             });         }          else         {             \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u043b\u044e\u0447 \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430            \/\/ \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0431\u0435\u0440\u0451\u043c PartialLoader \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c            \/\/ \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e.             key = context.Request.Headers[Constants.PartialLoaderSessionKey];             partialLoader = loaderStorage.Data[key];             await partialLoader.ContinueAsync();         }          \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0432\u0435\u0442\u0430, \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0438\u0439, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u044d\u0442\u043e \u043f\u0430\u0440\u0442\u0438\u044f        \/\/ \u0438\u043b\u0438 \u043d\u0435\u0442.         context.Response.Headers.Add(Constants.PartialLoaderStateHeaderName,                                      partialLoader.State.ToString());              if(partialLoader.State == PartialLoaderState.Partial)             {                 \/\/ \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0442\u0438\u044f \u043d\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f,                  if(key is null)                 {                     \/\/ \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0442\u0438\u044f \u043f\u0435\u0440\u0432\u0430\u044f, \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447 \u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c                    \/\/ IPartialLoader \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435.                     key = Guid.NewGuid().ToString();                     loaderStorage.Data[key] = partialLoader;                 }                 \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0432\u0435\u0442\u0430 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c.                 context.Response.Headers.Add(                   Constants.PartialLoaderSessionKey, key);             }             else             {                 \/\/ \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0442\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f, \u0443\u0434\u0430\u043b\u044f\u0435\u043c IPartialLoader \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430.                 if (key is not null)                 {                     loaderStorage.Data.Remove(key);                 }             }               await context.Response.WriteAsJsonAsync&lt;List&lt;Cat>>(               partialLoader.Chunk);         }     } <\/code><\/pre>\n<ul>\n<li>\n<p><code>BigCatsDataClient<\/code> &#8212; \u043f\u0440\u043e\u0435\u043a\u0442 WPF. \u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0430 \u0432 code-behind \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u044b \u043c\u0435\u0442\u043e\u0434\u044b, \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u0448\u0435\u043a \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u0447\u0430\u0441\u0442\u044f\u043c\u0438. \u041a\u043e\u0434 \u0434\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e, \u043e\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cs\">private const string Server = \"https:\/\/localhost:7209\";  \/\/\/ &lt;summary xml:lang=\"ru\"> \/\/\/     \u041c\u0435\u0442\u043e\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \/\/\/ &lt;\/summary> private async Task GetAllCats() {   ...     try     {       ...         using HttpClient _client = new HttpClient();         ...         _client.BaseAddress = new Uri(Server);          \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0432 \u0441\u0442\u0438\u043b\u0435 REST         HttpRequestMessage request = new<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-330105","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330105","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=330105"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330105\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=330105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=330105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=330105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}