Implement Asynchronous Scanning in PCL and Windows Phone Applications

For some strange reason, both System.Runtime.Remoting.Messaging.CallContext and AsyncLocal are only available using the full CLR. This makes it very difficult to work with asynchronous coverage when working with portable class libraries or Windows Phone applications, especially since the Windows Phone APIs become async-only; therefore, we really do not have the option not to use async / wait.

What this actually means is that in WPF or WinForms we can write such methods:

private async void button_Click(object sender, EventArgs e) { CallContext.LogicalSetData("x", new object()); await Something(); var context = CallContext.LogicalGetData("x"); } 

In WPF and WinForms, the structure ensures that each click on the same button gets its own context, and this can work in isolation. It is difficult to achieve the same value with ThreadLocal<T> and [ThreadStatic] , since each click will be executed in the user interface thread.

My question is: how to solve this problem in Windows Phone, Store and other types of applications that do not support CallContext and AsyncLocal<T> ?

Some background information:

Very often we want (business logic) to work in some context. This context may contain information that business logic can use throughout the operation. In a server environment, this is very easy to imagine, because you need to run queries in a database transaction, you need to have access to the current user, tenant ID, etc. But even in a client application, operations may require access to contextual information, such as a correlation identifier for the current current operation or a context for logging. During such an operation (for example, the click event), we may need to allow additional services (from Root of Composition ). For the operation to work successfully, we may need to reuse the same component throughout the operation with the client, which means that our root structure must know about the running context.

Although all this information can be transmitted through the entire system using calls to public API methods, it would not only cause us to pollute the API services in our application with implementation details, it would lead to serious ones because we would have to go through all this information on the whole system, and a simple internal change to one of our components would spread the call stack through all the method calls. And when it comes to our Root Composition, we definitely don't want to go through any cache / area object of our DI library through the application, because it will closely link our business logic with an external library. Obviously, we do not want to pass some kind of service locator .

Thus, implementing applications using something like CallContext or AsyncLocal<T> very important in client applications.

+6
source share
1 answer

There is no easy solution today, sorry. When the Windows Phone (over time) becomes "Windows 10 on the phone" (i.e. With AsyncLocal<T> ), then it will be possible. But now...

The easiest way to do this is to pass the context either explicitly (as a parameter) or implicitly (as a member variable in this ).

A limited version of this with custom expectations can also be achieved. But in addition to being terribly complex, for this solution you will need to change each await in your entire application (or use recompilation of IL code to achieve the same effect).

+3
source

All Articles