Skip to content
blackcity edited this page Jul 15, 2013 · 1 revision

###Asynchronous operations with async/await, Tasks and Threads Backload internally uses asynchronous operations and also supports and encourages this for your extensions. Asynchronous code does not block the UI thread when long running operations (File I/O, web requests, etc) have to be done. Multiple long running operations can be executed in parallel. Backload simplifies developing asynconous code with the relatively new .NET feature async/await and Tasks. For more information on async/await and Tasks please refer to the documentation on MSDN. In this example, we've created multiple demos to show you different ways to work with asynchronous tasks within your extensions code. We will show you if and when results of long running tasks will be awaited. Note: The settings in this example for the client side plugins are for modern browsers only (JQuery > 2.0). Older Browsers (e.g. IE8 and below) are not supported.

####How to use this example We have 5 extensions in this example (2 GetFilesRequest extensions, a DeleteFilesRequest extension, a StoreFileRequest extension an an OutgoingResponse extension for PlUpload). Open the extensions in Visual Studio and set breakpoint at the beginning of the code. Keep in mind, when changing the code of an extension, rebuild the extensions project. The output path is set to the ~/bin/extensions folder of the main MVC application so the application will use the current extension assembly. Otherwise you may use the old assembly. First, go to the GetFilesRequest extension and note, that we've simulated a long running task with this line of code:

var t = Task.Run(() => Task.Delay(System.TimeSpan.FromSeconds(10)));

####Demo 1: We do not await the result of the task Run the solution. In this demo, we do not care about (await) the results of this task, so it does not block and we get the results almost instantly. The task runs as a background thread within the AppDomains thread pool. You should not use this technique with a file IO, because the thread may be aborted when Backload returns. In the next demos we await the result maybe because we need to make sure that the task succeeded.

####Demo 2: Using the await keyword to await the result immediately Uncomment the line below, set breakpoints (also in the GetFilesRequest2 extension) and rebuild the extension and run the solution. You'll notice that debugging stops and awaits the result of the task. The subsequent code and extensions are not executed until the task is finished. But, the ui thread is not blocked and tied up and the operating system can do other work. You can see this, because the web page comes back. Usually, when executing and debugging synchronous code, the web page only shows up when the code returns.

await t;

####Demo 3: Use ExtensionTasks to await the result before the next extension is called Comment out the await line above, uncomment the line below, set breakpoints and rebuild the extension and run the solution. The debugging now doesn't stop and the extension returns. Before calling the next extension within this extension point, the extension manager awaits the result. Note that the second extension below isn't executed until the task is finished.

PipelineControl.TaskManager.ExtensionTasks.Add(t);

####Demo 4: Use ExtensionPointTasks to await the result after all extensions returned Comment out the await line above, uncomment the line below, set breakpoints and rebuild the extension and run the solution. When debugging the application you'll see, that the second extension also can execute and finish its code, before the extension manager awaits the result at the end of the extension point (before code execution returns to the pipeline).

PipelineControl.TaskManager.ExtensionPointTasks.Add(t);

####Demo 5: Use PipelineExtendedTasks to await the result before Backload returns Comment out the await line above, uncomment the line below, set breakpoints and rebuild the extension and run the solution. Make sure you have set a breakpoint in the OutgoingResponse extension where the response for the PlUpload plugin is generated. Maindifference to the code above is, that the OutgoingResponse extension was called before the Pipeline waits for the result of the task. PipelineExtendedTasks is ultimately the last point in the processing pipeline before the Pipeline returns the results to the client.

PipelineControl.TaskManager.PipelineExtendedTasks.Add(t);

####Demo 6: Use Task.Run(...) and wait for the results Now go to the DeleteFiles extension. When we uploaded a file, we made copies in the ~/Files/_Backup and the ~/Files/_Temp folders. In a DELETE request we want to delete those files too. In this demo we use Task.Run() to execute the delete method by a thread of the AppDomains thread pool. Note that we await the result of the task; otherwise the thread may be aborted when Backload returns and not all files were deleted.

   var t = Task.Run(() => DeleteTempFiles(dirTemp, file.FileName));
   PipelineControl.TaskManager.ExtensionPointTasks.Add(t);

####Demo 7: Use a separate thread to do work independently Now go to the StoreFile extension. In this demo we do our work in a separate thread and do not care about the result (fire&forget strategy). Because we cannot be sure that the thread finished the work successfully be careful with this approach. If you rely on the results, use Thread.Join(), async/await, the task based approach or check if the files exist in another extension, a subsequent request, a different code or even another application.

   new System.Threading.Thread(new System.Threading.ThreadStart(new MuchToDo(File, localBackupPath).WriteFiles)).Start();

####Conclusion In this example you learned some techniques to develop asynchronous code for File I/O, web requests or other long running operations. The easiest way to develop asynchronous code is to make use of the new async and await keywords and to use tasks. Backload provides several scopes where to await (multiple) results of tasks. Whenever possible you should use the asynchronous operations .NET provides, e.g. FileStream.WriteAsync() etc.

Code

Code examples: Example11


License

Backload. (Standard version): Copyright 2013, Steffen Habermehl, License (Standard version): MIT license
Professional and Enterprise (source code) version are available under a commercial license.
Follow us on Twitter: @Backload_MVC

Clone this wiki locally