YouTube2Text

1С зависает? Переносим код в фон через БСП + показываем прогресс — Transcript

by IRONSKILLS - Курсы по 1С · 3,942 words · 617 segments · language en · Watch on YouTube

Full transcript

  1. 0:00Before you is a slightly customized 1Sf
  2. 0:01configuration. A "Manual Discount"
  3. 0:04button has been added to the customer
  4. 0:05order list form, and here is how it
  5. 0:07works. The user selects many orders in
  6. 0:09the list, clicks the "Manual Discount"
  7. 0:11button, enters a discount percentage,
  8. 0:12and the discount is applied to all
  9. 0:14selected orders. Essentially, the order
  10. 0:16totals are recalculated, and the orders
  11. 0:18are then reposted. Here is how it works
  12. 0:19right now. I will select a large number
  13. 0:21of orders at once. Next, I click the
  14. 0:23button and specify a discount
  15. 0:24percentage, say 10%. We click "OK". And
  16. 0:27the programmatic modification of the
  17. 0:28orders takes place. But while this is
  18. 0:30happening, I cannot do anything else.
  19. 0:31That is, the interface is blocked, and
  20. 0:33I cannot navigate anywhere. Only after
  21. 0:35the operation finishes will I see that
  22. 0:3736 orders have been processed. How can
  23. 0:40I ensure that the program interface
  24. 0:42does not block when I click the button?
  25. 0:44I would like to continue working, such
  26. 0:47as opening other lists or generating
  27. 0:49reports, without waiting for this
  28. 0:51operation to finish. Hi, my name is
  29. 0:53Vanya, and this is the Iron Skills
  30. 0:55channel. Here we talk about 1C
  31. 0:56development. And in this video, we will
  32. 0:59discuss background execution of
  33. 1:00long-running operations. Let's not
  34. 1:02waste time, let's go. Let's start with
  35. 1:04the fact that there is a development
  36. 1:06standard. I will leave a link to it in
  37. 1:07the description below this video. The
  38. 1:10standard states that all long-running
  39. 1:12server calls that may take more than 8
  40. 1:14seconds in normal user scenarios should
  41. 1:16be performed asynchronously using a
  42. 1:18background job. It then describes in
  43. 1:20detail which tools exist for this
  44. 1:22purpose, specifically in the Standard
  45. 1:24Subsystems Library. And we can use this
  46. 1:26in all standard configurations, as they
  47. 1:28contain the SSL. And I will show you
  48. 1:31how to use it right now with examples.
  49. 1:33Let's switch to the Configurator of
  50. 1:34this database. First, I will show how
  51. 1:36the customization is implemented. It is
  52. 1:37implemented via a configuration
  53. 1:39extension; that is, an extension was
  54. 1:40created, and the list form was added to
  55. 1:42it. Then, first of all, in the form's "
  56. 1:44OnCreateAtServer" event handler, the
  57. 1:46command and the corresponding button
  58. 1:48are created programmatically. The
  59. 1:50command handler is a client procedure
  60. 1:52called "Apply Manual Discount." In this
  61. 1:55procedure, we retrieve the selected
  62. 1:56orders from the list and check how many
  63. 1:58there are. If there are none, then
  64. 2:00there is no point in proceeding. If at
  65. 2:01least one order is selected, we prompt
  66. 2:03the user for the discount percentage.
  67. 2:05Then, a server function is called, to
  68. 2:07which we pass an array of order
  69. 2:08references and the discount percentage
  70. 2:10to be applied to these orders. Within
  71. 2:13this function, code is written that
  72. 2:15loops through all the orders. It
  73. 2:17retrieves the object, modifies the data
  74. 2:19in the tabular section—that is, it
  75. 2:21sets the discount percentage for each
  76. 2:23row and calls the function to
  77. 2:24recalculate the row totals—after
  78. 2:26which it programmatically writes or
  79. 2:27reposts the document, depending on
  80. 2:29whether it was just written or posted.
  81. 2:32And this function counts the number of
  82. 2:34modified orders. This quantity is
  83. 2:35returned to the client, after which the
  84. 2:37list is updated on the client side so
  85. 2:39the user immediately sees that the
  86. 2:41totals have changed, and a notification
  87. 2:42is displayed stating how many orders
  88. 2:44were modified. Now, let's look at how
  89. 2:46to move server-side code to background
  90. 2:48execution. For this, we will use the
  91. 2:49SSL (Standard Subsystems Library) and
  92. 2:51procedures located in common modules.
  93. 2:53They are called: Long-running
  94. 2:54operations and Long-running operations
  95. 2:56client. We need to ensure that this
  96. 2:59server function, which handles
  97. 3:00programmatic modification of orders and
  98. 3:02their reposting, runs in the background
  99. 3:04. That is, a separate background job
  100. 3:06should be responsible for the execution
  101. 3:07. For the job to be able to execute
  102. 3:09this procedure, it must be placed in a
  103. 3:11different module. This could be a
  104. 3:13common module, an object manager module
  105. 3:15, or an object module. Most often, a
  106. 3:18common module or manager module is used
  107. 3:21. I will take the path of creating a
  108. 3:23common module. So, I create a common
  109. 3:24module and name it, for example, like
  110. 3:26this. "CustomerOrderProcessing". For
  111. 3:29this, we also check the "External
  112. 3:31connection" checkbox. And we move this
  113. 3:32function from the form module to the
  114. 3:34common module. Here we remove the
  115. 3:36compilation directive. We will also
  116. 3:38slightly change the name of this
  117. 3:39function. I will leave it as "Apply
  118. 3:41manual discount to orders". We just
  119. 3:43make it mandatory to export so that it
  120. 3:45can be called. And let's designate a
  121. 3:47region here: "Program interface". Where
  122. 3:49we will place this function. Checking
  123. 3:51the syntax. No errors. We return back
  124. 3:53to the form module. Now we need to
  125. 3:56ensure that the common module function
  126. 3:58is called, but not directly; rather, it
  127. 4:00should be called as part of a
  128. 4:01background job. To do this, we will
  129. 4:04need to call specific procedures from
  130. 4:06the Long-running operations common
  131. 4:07module. The code that currently calls
  132. 4:09the function will be commented out. And
  133. 4:11I will place the client-side part
  134. 4:12within separate procedures, because I
  135. 4:14will be showing you different examples.
  136. 4:16So, the first example. Let's look at
  137. 4:18how to ensure this server procedure
  138. 4:20executes in the background without
  139. 4:21displaying a progress bar. I will be
  140. 4:23copying code fragments. Some procedures
  141. 4:25are already prepared in advance. I will
  142. 4:26also attach them to the description
  143. 4:28under this video later. On the client,
  144. 4:30we need to initiate a call to the form
  145. 4:32module server function. We will add
  146. 4:34this function here now as well. It will
  147. 4:35be called "Start discount application".
  148. 4:37In this server function, we have
  149. 4:39references to the orders that need to
  150. 4:41be changed and the discount percentage.
  151. 4:43Our main task is to call the
  152. 4:44Long-running operations common module,
  153. 4:46the "Execute function" method. A
  154. 4:47special structure, execution parameters
  155. 4:49, is passed there. There is a
  156. 4:50constructor for this structure. It is
  157. 4:52another function of the common module.
  158. 4:53"Long-running operations" is called "
  159. 4:54Function execution parameters". The
  160. 4:55second parameter is the path to the
  161. 4:57function or procedure that should be
  162. 4:59executed in the background. In our case
  163. 5:00, it is the common module "
  164. 5:02CustomerOrderProcessing" and then the
  165. 5:03function name. "Apply manual discount".
  166. 5:06The procedure or function of the common
  167. 5:07module that we call in the background
  168. 5:08can have parameters, and we have them:
  169. 5:10these are orders and the discount
  170. 5:11percentage. And for these parameters to
  171. 5:14be passed, we must list them in the "
  172. 5:15execute function" method after the
  173. 5:17procedure or function name, separated
  174. 5:19by commas, in the exact order they
  175. 5:20should be passed there. Moreover, there
  176. 5:23can be up to seven parameters. If you
  177. 5:24go to the common module and look at the
  178. 5:26syntax for the "execute function," it
  179. 5:28will state that we can have up to seven
  180. 5:30parameters, which can simply be passed
  181. 5:32one after another, separated by commas.
  182. 5:33And accordingly, the orders will be
  183. 5:35passed here, and the discount
  184. 5:37percentage here. The "execute function"
  185. 5:39method returns a special structure,
  186. 5:40essentially containing a description of
  187. 5:42the started background job, and we
  188. 5:43receive it on the client side to track
  189. 5:45when this job is finished. The next
  190. 5:47stage on the client side is waiting for
  191. 5:50the job to complete. For this, we use
  192. 5:52the client-side common module "
  193. 5:53Long-Running Operations Client" and the
  194. 5:55special method "wait for completion."
  195. 5:56Here we must pass the structure
  196. 5:58describing the started job as the first
  197. 6:00parameter and the completion
  198. 6:02notification as the second parameter.
  199. 6:04This determines which procedure will be
  200. 6:05called when the job finishes. Either
  201. 6:07successfully, or, for example, if the
  202. 6:09user cancels it. In our case, this
  203. 6:11procedure will be called "after
  204. 6:12applying discount." I will copy this
  205. 6:14procedure here into our module. And in
  206. 6:16the procedure that will be called after
  207. 6:18the background job finishes, we will
  208. 6:20have two parameters. These are the
  209. 6:22result and additional parameters. The
  210. 6:24result is a structure. And this
  211. 6:26structure contains an important key:
  212. 6:28the status. By the status, we can
  213. 6:30understand whether the job was executed
  214. 6:32successfully or if an error occurred.
  215. 6:35The possible scenarios can all be
  216. 6:36viewed at the level of this "wait for
  217. 6:37completion" method. Let me drill down
  218. 6:40into this. Let's open the description.
  219. 6:42And it states here that the result is a
  220. 6:44new long-running operation result.
  221. 6:46Meaning, it is a structure like this.
  222. 6:47This is what we will get as a result.
  223. 6:49Specifically: status, result address,
  224. 6:51and error information, if any error
  225. 6:53occurred. And a job identifier may also
  226. 6:55be present there. The result address is
  227. 6:57the address of data in the temporary
  228. 6:59storage where the function execution
  229. 7:01result is located. For example, look
  230. 7:03here. In our case, in the common module
  231. 7:05, where we moved this function, it
  232. 7:06returns a value, which is the number of
  233. 7:08processed orders. The function will be
  234. 7:10executed by a background job. And to
  235. 7:12get the result of this function's
  236. 7:14execution, we must use this very key:
  237. 7:16the result address. I will return to
  238. 7:18the form module. In the "after applying
  239. 7:20discount" procedure, which will be
  240. 7:22called when the job is done, we can
  241. 7:24access the result address via the
  242. 7:26result and retrieve the outcome from
  243. 7:28the temporary storage. And this will be
  244. 7:30the number of processed orders in this
  245. 7:32case. Well, if, for example, you were
  246. 7:34calling some function that returns, say
  247. 7:36, a reference to a document, or an
  248. 7:37array of references, then we would get
  249. 7:39an array of references. In other words,
  250. 7:41this is what the function called in the
  251. 7:42background essentially returns. And the
  252. 7:43logic after the background job
  253. 7:45completes is as follows. We check the
  254. 7:46execution status. If it is an error, we
  255. 7:49display an error message. If the job
  256. 7:50was canceled, we simply exit the
  257. 7:52procedure. And if the background job
  258. 7:54completed successfully, the third
  259. 7:55scenario, in this case, we get the
  260. 7:57result of the function execution,
  261. 7:58retrieve it from the temporary storage,
  262. 8:00update the list, and show a
  263. 8:02notification to the user that the job
  264. 8:03is done and a certain number of orders
  265. 8:05were processed. Well, now let's see how
  266. 8:07this will work. I see there is an error
  267. 8:09, yes, I am not passing two more
  268. 8:11parameters. We will fix that now.
  269. 8:13Checking the syntax. Updating the
  270. 8:15database configuration. Starting the
  271. 8:16session. Going to the customer orders
  272. 8:19list. I will select several documents.
  273. 8:21I will click the manual discount button
  274. 8:22. And let's assign 5%. Clicking OK. And
  275. 8:26a window like this appears. The
  276. 8:27interface is not blocked, so I can
  277. 8:29calmly continue working. And we see
  278. 8:30that a lengthy operation is being
  279. 8:31performed. When it finished, we
  280. 8:33received a notification that a certain
  281. 8:35number of orders were processed. Now
  282. 8:36let's consider the next option. Suppose
  283. 8:39that right now, when the lengthy
  284. 8:41operation window opens, we see some
  285. 8:43standard text here. Lengthy operation.
  286. 8:45Please wait. If we want to show our own
  287. 8:47text, how is this implemented? I will
  288. 8:50describe this within a separate client
  289. 8:51procedure. It will be called "Apply
  290. 8:53discount in background option two," and
  291. 8:55through its example, I will show you
  292. 8:57how to manage the parameters of this
  293. 8:59window. I will also add the procedure
  294. 9:01to the module. The difference will be
  295. 9:03that here we must describe a special
  296. 9:05structure. It is called waiting
  297. 9:06parameters and can be obtained via the
  298. 9:08common module "Lengthy operations
  299. 9:10client" and the "waiting parameters"
  300. 9:11function. The current form is passed
  301. 9:13there. And then, in this structure,
  302. 9:15there is, for example, the window title
  303. 9:17and the message text that we want to
  304. 9:19show. And we pass the waiting
  305. 9:20parameters to the "wait for completion"
  306. 9:21method. So, in the first option, we
  307. 9:23only passed the structure with
  308. 9:24information about the lengthy operation
  309. 9:26and the completion notification to "
  310. 9:27wait for completion." Here we can also
  311. 9:29pass these waiting parameters, which
  312. 9:31allow overriding the window. I will
  313. 9:33comment out the call to the first
  314. 9:34client procedure and see what the
  315. 9:35difference will be. Otherwise,
  316. 9:37everything remains the same. So here we
  317. 9:38didn't touch anything else, only the
  318. 9:40call to the "wait for completion"
  319. 9:42method on the client. Going to Sales,
  320. 9:45customer orders. I will select more
  321. 9:47orders. Manual discount. And let's
  322. 9:48reset it, for example. I press zero
  323. 9:50here. OK. And now a window appears with
  324. 9:53our text. Applying the discount and
  325. 9:55performing changes to selected customer
  326. 9:57orders. Moving on. Now I also want to
  327. 10:00see execution progress to understand
  328. 10:02what percentage of the task is complete
  329. 10:04and how this scenario is implemented.
  330. 10:06To implement the display of execution
  331. 10:08progress, we first need to change the
  332. 10:09waiting parameters. When calling the
  333. 10:11wait for completion method. I will copy
  334. 10:13the procedure name. We will now call a
  335. 10:16procedure that will be called option
  336. 10:18three. I will copy it and show the
  337. 10:20difference specifically on the client.
  338. 10:22So, we have initiated a long-running
  339. 10:24operation. Then we want to wait for its
  340. 10:26completion, and we set the wait
  341. 10:28parameters. In the wait parameters, we
  342. 10:30have previously set the title and
  343. 10:32message text. And to also show
  344. 10:34execution progress, we enable a
  345. 10:35parameter here called display execution
  346. 10:37progress, set to true. There is also an
  347. 10:39interval parameter that allows you to
  348. 10:41set the polling interval for task
  349. 10:42readiness. You can look at more details
  350. 10:44in the description of this wait
  351. 10:45parameter function. Here, by going into
  352. 10:47the comments, you will see that the
  353. 10:49interval is the number of seconds
  354. 10:50between readiness checks. By default it
  355. 10:53is zero, which means that after each
  356. 10:54check the interval increases from one
  357. 10:56to 15 seconds with a factor of 1, but
  358. 10:58we will just set it to one. That is,
  359. 11:00the task will be polled for its
  360. 11:02readiness every second. That is not all
  361. 11:05. Besides changing the wait parameters,
  362. 11:08we must also ensure our server function
  363. 11:10reports the completion percentage,
  364. 11:11because how would the platform know how
  365. 11:13ready our function is, since the logic
  366. 11:15there can be completely different?
  367. 11:18Therefore, we go to our main server
  368. 11:20function, which runs in the background,
  369. 11:22and add a call to a special method from
  370. 11:24the long-running operation common
  371. 11:26module. When our order is saved, we
  372. 11:28increment the counter of processed
  373. 11:31orders. Right here we call long-running
  374. 11:33operations report progress. And we pass
  375. 11:36the progress value in percent that we
  376. 11:38calculated, plus some text so it is
  377. 11:40clear how many orders we have processed
  378. 11:43. So, to implement the display of
  379. 11:45execution progress, first, we must
  380. 11:47enable progress display in the wait
  381. 11:49parameters when calling the wait for
  382. 11:51completion method. That is one. And
  383. 11:53second, in our main server procedure
  384. 11:55running in the background, we must
  385. 11:57explicitly add a progress message.
  386. 11:58Updating the database configuration.
  387. 12:00Let's launch a session and see what has
  388. 12:02changed. So, Sales, Customer Orders.
  389. 12:04Select a larger list of documents,
  390. 12:06manual discount. Set 5%, click OK. So,
  391. 12:09a window opens. And here we can already
  392. 12:12see the task execution in percent.
  393. 12:15Result: 27 orders processed. I will
  394. 12:18also show you a diagram of how this
  395. 12:19works. We have a client, a server, and
  396. 12:21a background task. On the client side,
  397. 12:23we receive an array of references to
  398. 12:25the orders that need to be changed from
  399. 12:26the user, along with the discount
  400. 12:27percentage. Next, on the server, again
  401. 12:29in the form module, we initiate the
  402. 12:31launch of a background job. For this,
  403. 12:33we use the "Long-running operations"
  404. 12:35common module and the "Execute function
  405. 12:37" or "Execute procedure" methods. We
  406. 12:39pass the name of the procedure or
  407. 12:40function to be executed there, plus a
  408. 12:42set of parameters. From that point on,
  409. 12:43the SSL (Standard Subsystems Library)
  410. 12:44handles everything for us. That is, the
  411. 12:46SSL method launches the background job
  412. 12:48and receives information about it in
  413. 12:50the form of a structure. We then
  414. 12:53receive this structure on the client
  415. 12:55side and can use it to wait for the job
  416. 12:58to complete. Having received the
  417. 13:01structure with information about the
  418. 13:03background job from the server function
  419. 13:05, we call the "Long-running operations
  420. 13:08client" and the "Wait for completion"
  421. 13:10method, passing in this long-running
  422. 13:12operation structure along with the info
  423. 13:14on which of our procedures to call when
  424. 13:16the job finishes. Then, the job
  425. 13:19continues to run and run. If we need to
  426. 13:21report execution progress, we forcibly
  427. 13:23add a call to the "Report progress"
  428. 13:24method within the function running in
  429. 13:26the background. That means we calculate
  430. 13:28the progress ourselves, and it is also
  431. 13:30displayed on the form. When the job
  432. 13:32finishes, the platform calls our
  433. 13:34procedure that we specified as the
  434. 13:36completion handler, passing the result,
  435. 13:38which contains the job execution status
  436. 13:41plus the address of the background
  437. 13:43function's result. Based on the status,
  438. 13:45we determine what the final outcome was
  439. 13:47. That is, whether the job completed
  440. 13:49successfully, failed with an error, or
  441. 13:50was canceled. If it completed, we can
  442. 13:53then use the result address to retrieve
  443. 13:54the function's execution result from
  444. 13:56temporary storage and do something with
  445. 13:58it. For example, in our case, we simply
  446. 14:00display information about how many
  447. 14:01orders were processed. That is how it
  448. 14:03works in a single thread, but there is
  449. 14:05also an option for multi-threaded
  450. 14:07execution of certain code in the
  451. 14:09background. I will show you how to do
  452. 14:11this now. First, I will explain the
  453. 14:13scheme of how it works. Let's start
  454. 14:14with the common module function.
  455. 14:16Currently, the function running in the
  456. 14:18background processes all orders. That
  457. 14:20is, we have an "orders" parameter,
  458. 14:21which is an array of references to the
  459. 14:23orders that need processing. If we want
  460. 14:25to process orders in multiple threads,
  461. 14:27we need to split this list into chunks.
  462. 14:29In our case, a chunk can be a single
  463. 14:31order. This means we need a function
  464. 14:34that will apply a discount to one order
  465. 14:36rather than to a list of orders. And,
  466. 14:38in principle, we can describe this
  467. 14:40function right here and now. I already
  468. 14:42have it prepared. Everything in it is
  469. 14:44the same, the logic is absolutely
  470. 14:45identical, just a different parameter.
  471. 14:46That is the order reference. And there
  472. 14:48is no loop here. We simply get the
  473. 14:50order, modify it, and repost it. Now
  474. 14:52let's move on. When we have a function
  475. 14:55like this that processes exactly one
  476. 14:56order, we can process them in multiple
  477. 14:58threads. The logic is as follows. On
  478. 15:01the client, we form a map with a set of
  479. 15:03possible function parameters. In other
  480. 15:06words, these are the sets of parameters
  481. 15:08with which this function needs to be
  482. 15:10called. So, first we must call this
  483. 15:12function to apply a discount to one
  484. 15:14order by passing the first order and a
  485. 15:15discount percentage, say 5%, here. Then
  486. 15:17the second order and a discount
  487. 15:18percentage of five. And so we generate
  488. 15:20this entire set on the client. Then, on
  489. 15:22the server, we call the common
  490. 15:24long-running operations module. It has
  491. 15:27a specific method called execute
  492. 15:29function in multiple threads. And we
  493. 15:31pass that set of parameters and the
  494. 15:33function we want to call with different
  495. 15:34sets of parameters to it. From there,
  496. 15:36the BSP will handle everything for us.
  497. 15:37The method from the common long-running
  498. 15:39operations module. It first starts a
  499. 15:41control thread. This is a parent task
  500. 15:43that subsequently spawns execution
  501. 15:45threads—these are background jobs
  502. 15:47that will call the function with
  503. 15:49different parameter sets. So, the first
  504. 15:52thread will take a set of parameters
  505. 15:54from the queue, say, order 1 with 5%,
  506. 15:55and start working with it. The second
  507. 15:57thread will take the next order from
  508. 15:59the queue and start working with it.
  509. 16:00And so they will be able to process
  510. 16:02this entire queue in parallel. When all
  511. 16:04tasks are completed, the control thread
  512. 16:07receives this information and finishes
  513. 16:09its task. Then a procedure is called in
  514. 16:12the form module where we receive the
  515. 16:14execution result. Well, the logic here
  516. 16:16is the same as in the first option.
  517. 16:17That is, we get the result, which will
  518. 16:19include the execution status—
  519. 16:20completed, error, or canceled—and we
  520. 16:22can get the address of the function
  521. 16:24execution result. An important point is
  522. 16:26that multithreaded background execution
  523. 16:28of code is only possible if we can
  524. 16:30truly process these portions of data
  525. 16:32independently of each other. For
  526. 16:36example, if we had a slightly different
  527. 16:37task, like needing to repost documents
  528. 16:39for the same warehouse. We wouldn't be
  529. 16:42able to do this in parallel anyway,
  530. 16:44because you cannot simultaneously post
  531. 16:46two documents deducting the same items
  532. 16:48from one warehouse, as it would cause
  533. 16:50lock contention. Therefore, it is
  534. 16:52important to keep in mind that this
  535. 16:54multithreading can only be applied in
  536. 16:56cases where we can truly process or
  537. 16:58modify data independently of each other
  538. 17:00. In our case, this is possible. I mean
  539. 17:02, posting one order will not lead to me
  540. 17:04interfering with the operation of
  541. 17:05another thread in parallel. This is the
  542. 17:07general scheme. Now let's return to the
  543. 17:09configurator and implement this. I have
  544. 17:10already added the function here. So, in
  545. 17:12the common module, we have the function
  546. 17:13that processes exactly one order and
  547. 17:14applies a discount to it. Now we move
  548. 17:16on to the form module. And here we will
  549. 17:19need to call "Apply Discount in
  550. 17:21Background Option 4". Let's add this
  551. 17:24procedure here. The difference will be
  552. 17:26as follows. Regarding the waiting
  553. 17:28parameters, it is all the same. That is
  554. 17:29, we will also display the execution
  555. 17:31progress here. And we also call "wait
  556. 17:32for completion", but the difference
  557. 17:34will be in the server function itself,
  558. 17:36because it won't be called like in the
  559. 17:38other options where we use the same "
  560. 17:39Start Applying Discount", here we need
  561. 17:41to call it slightly differently,
  562. 17:42because it needs to form a set of
  563. 17:44parameters. Therefore, I am defining a
  564. 17:46separate function that will be called "
  565. 17:48Start Applying Discount in Multiple
  566. 17:49Threads". Here, first, we create a map
  567. 17:51of parameter sets on the client, and
  568. 17:54using the array of orders and the
  569. 17:56discount percentage, we form this map
  570. 17:58and populate it. The key in this map,
  571. 18:00in our case, will be the reference to
  572. 18:01the order, and the set of parameters is
  573. 18:03an array with our function's parameters
  574. 18:05. We have two of them, so we add them
  575. 18:07here. Then we call the "Execute
  576. 18:08Function in Multiple Threads" function
  577. 18:09from the common module of long-running
  578. 18:11operations. We pass the name of the
  579. 18:13function to be executed in the
  580. 18:14background, the execution parameters,
  581. 18:16and this map with the sets of
  582. 18:17parameters. And that is basically it.
  583. 18:21Note that we do not specify the number
  584. 18:22of threads to be launched anywhere here
  585. 18:24. The fact is that the number of
  586. 18:26threads here is determined
  587. 18:27automatically by the SLP (Standard
  588. 18:28Subsystems Library) itself. There is a
  589. 18:31constant that allows you to limit the
  590. 18:33maximum number of threads. It is called
  591. 18:35"Number of long-running operation
  592. 18:37threads". So, I will update the
  593. 18:38database configuration. Starting the
  594. 18:40session. My database is file-based, so
  595. 18:42we won't notice any effect right now,
  596. 18:43of course. But first, let me go to "
  597. 18:45Functions for Technical Specialist" and
  598. 18:47set the value of this constant. "Number
  599. 18:49of long-running operation threads".
  600. 18:51Let's set it to four. Then let's go to
  601. 18:54Sales, Customer Orders. Let's select
  602. 18:56more orders. I click "Manual discount"
  603. 18:58and, let's say, 10%, applying it. Click
  604. 19:01"OK". And the background task is
  605. 19:03running. But at the same time, the
  606. 19:04execution is now taking place in
  607. 19:06multiple threads. Well, it's clear that
  608. 19:07this will only work fully in the
  609. 19:09client-server version. In the file
  610. 19:11version, I will essentially still have
  611. 19:12only one thread. Thank you for watching
  612. 19:14. You will find all the examples from
  613. 19:16today's video in the description.
  614. 19:17Subscribe to us, give us a like. My
  615. 19:19name is Vanya, this is the Iron Skills
  616. 19:21channel. Here we talk about 1C
  617. 19:22development. Bye. M.

About this transcript

This page contains the full transcript of 1С зависает? Переносим код в фон через БСП + показываем прогресс by IRONSKILLS - Курсы по 1С, generated from the public captions YouTube serves with the video. The transcript has 3,942 words across 617 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.