Search Results

Search found 10838 results on 434 pages for 'adf task flow'.

Page 31/434 | < Previous Page | 27 28 29 30 31 32 33 34 35 36 37 38  | Next Page >

  • Adaptive Connections For ADFBC

    - by Duncan Mills
    Some time ago I wrote an article on Adaptive Bindings showing how the pageDef for a an ADF UI does not have to be wedded to a fixed data control or collection / View Object. This article has proved pretty popular, so as a follow up I wanted to cover another "Adaptive" feature of your ADF applications, the ability to make multiple different connections from an Application Module, at runtime. Now, I'm sure you'll be aware that if you define your application to use a data-source rather than a hard-coded JDBC connection string, then you have the ability to change the target of that data-source after deployment to point to a different database. So that's great, but the reality of that is that this single connection is effectively fixed within the application right?  Well no, this it turns out is a common misconception. To be clear, yes a single instance of an ADF Application Module is associated with a single connection but there is nothing to stop you from creating multiple instances of the same Application Module within the application, all pointing at different connections.  If fact this has been possible for a long time using a custom extension point with code that which extends oracle.jbo.http.HttpSessionCookieFactory. This approach, however, involves writing code and no-one likes to write any more code than they need to, so, is there an easier way? Yes indeed.  It is in fact  a little publicized feature that's available in all versions of 11g, the ELEnvInfoProvider. What Does it Do?  The ELEnvInfoProvider  is  a pre-existing class (the full path is  oracle.jbo.client.ELEnvInfoProvider) which you can plug into your ApplicationModule configuration using the jbo.envinfoprovider property. Visuallty you can set this in the editor, or you can also set it directly in the bc4j.xcfg (see below for an example) . Once you have plugged in this envinfoprovider, here's the fun bit, rather than defining the hard-coded name of a datasource instead you can plug in a EL expression for the connection to use.  So what's the benefit of that? Well it allows you to defer the selection of a connection until the point in time that you instantiate the AM. To define the expression itself you'll need to do a couple of things: First of all you'll need a managed bean of some sort – e.g. a sessionScoped bean defined in your ViewController project. This will need a getter method that returns the name of the connection. Now this connection itself needs to be defined in your Application Server, and can be managed through Enterprise Manager, WLST or through MBeans. (You may need to read the documentation [http://docs.oracle.com/cd/E28280_01/web.1111/b31974/deployment_topics.htm#CHDJGBDD] here on how to configure connections at runtime if you're not familiar with this)   The EL expression (e.g. ${connectionManager.connection} is then defined in the configuration by editing the bc4j.xcfg file (there is a hyperlink directly to this file on the configuration editing screen in the Application Module editor). You simply replace the hardcoded JDBCName value with the expression.  So your cfg file would end up looking something like this (notice the reference to the ELEnvInfoProvider that I talked about earlier) <BC4JConfig version="11.1" xmlns="http://xmlns.oracle.com/bc4j/configuration">   <AppModuleConfigBag ApplicationName="oracle.demo.model.TargetAppModule">   <AppModuleConfig DeployPlatform="LOCAL"  JDBCName="${connectionManager.connection}" jbo.project="oracle.demo.model.Model" name="TargetAppModuleLocal" ApplicationName="oracle.demo.model.TargetAppModule"> <AM-Pooling jbo.doconnectionpooling="true"/> <Database jbo.locking.mode="optimistic">       <Security AppModuleJndiName="oracle.demo.model.TargetAppModule"/>    <Custom jbo.envinfoprovider="oracle.jbo.client.ELEnvInfoProvider"/> </AppModuleConfig> </AppModuleConfigBag> </BC4JConfig> Still Don't Quite Get It? So far you might be thinking, well that's fine but what difference does it make if the connection is resolved "just in time" rather than up front and changed as required through Enterprise Manager? Well a trivial example would be where you have a single application deployed to your application server, but for different users you want to connect to different databases. Because, the evaluation of the connection is deferred until you first reference the AM you have a decision point that can take the user identity into account. However, think about it for a second.  Under what circumstances does a new AM get instantiated? Well at the first reference of the AM within the application yes, but also whenever a Task Flow is entered -  if the data control scope for the Task Flow is ISOLATED.  So the reality is, that on a single screen you can embed multiple Task Flows, all of which are pointing at different database connections concurrently. Hopefully you'll find this feature useful, let me know... 

    Read the article

  • Sysprep and Capture task sequence failing using MDT 2010

    - by Nic Young
    I have created a Windows Deployment Services server in Windows 2008 R2. When I originally set it up I was able to successfully use MDT 2010 to create my boot images as well as creating task sequences that would sysprep and capture, and deploy my custom .wim files. Everything was working perfectly. About a month later I boot up my Windows 7 x86 image and run Windows updates to keep my image up to date. I then go and run my sysprep and capture task sequence and I get the following errors: I searched online for the cause of this error message and it just seems to be a generic permission denied type of error message. I then decided to completely rebuild my VM image from scratch and try again. I am still getting the same error messages as before. The following is what I have tried troubleshooting this issue: Troubleshooting: I have ensured that that UAC and the firewall is turned completely off when trying to capture the image. I have tried recreating the task sequence and making sure that the deployment share is updated. I have ensured that the local Administrator account is enabled and has the same password as specified in the task sequence. I have tried joining the computer to the domain and running the task sequence and I get a different error: I have attempted to run the script from the command prompt with "Run as Administrator" and I still receive the same errors above. For testing purposes I have ensured that Everyone has read/write access to my deployment share. I have spent days on trying to resolve this to no avail. Any ideas? EDIT: Below is the log info from C:\Windows\Deploymentlogs\BDD.log as requested. <![LOG[LTI Windows PE applied successfully]LOG]!><time="11:48:34.000+000" date="07-25-2012" component="LTIApply" context="" type="1" thread="" file="LTIApply"> <![LOG[LTIApply processing completed successfully.]LOG]!><time="11:48:34.000+000" date="07-25-2012" component="LTIApply" context="" type="1" thread="" file="LTIApply"> <![LOG[Microsoft Deployment Toolkit version: 6.0.2223.0]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[The task sequencer log is located at C:\Users\nicy\AppData\Local\Temp\SMSTSLog\SMSTS.LOG. For task sequence failures, please consult this log.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[Processing drivers for an X86 operating system.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[TargetOS is the current SystemDrive]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[Property DriverCleanup is now = DONE]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[Compare Image processor Type with Original [X86] = [X86].]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[Prepare machine for Sysprep.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[No driver actions can be taken for OS Images installed from *.wim files.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[ZTIDrivers processing completed successfully.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="ZTIDrivers" context="" type="1" thread="" file="ZTIDrivers"> <![LOG[Command completed, return code = -2147467259]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="1" thread="" file="LiteTouch"> <![LOG[Litetouch deployment failed, Return Code = -2147467259 0x80004005]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="3" thread="" file="LiteTouch"> <![LOG[For more information, consult the task sequencer log ...\SMSTS.LOG.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="1" thread="" file="LiteTouch"> <![LOG[Property RetVal is now = -2147467259]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="1" thread="" file="LiteTouch"> <![LOG[Unable to copy log to the network as no SLShare value was specified.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="1" thread="" file="LiteTouch"> <![LOG[CleanStartItems Complete]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="1" thread="" file="LiteTouch"> <![LOG[Unregistering TSCore.dll.]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="1" thread="" file="LiteTouch"> <![LOG[About to run command: wscript.exe "\\server\deploymentshare$\Scripts\LTICleanup.wsf"]LOG]!><time="11:48:35.000+000" date="07-25-2012" component="LiteTouch" context="" type="1" thread="" file="LiteTouch"> <![LOG[Microsoft Deployment Toolkit version: 6.0.2223.0]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Removing AutoAdminLogon registry entries]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[VSSMaxSize not specified using 5% of volume.]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Logs contained 7 errors and 0 warnings.]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Stripping BDD commands from unattend.xml template.]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Modified unattend.xml saved to C:\windows\panther\unattend.xml]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Checking mapped network drive.]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[testing drive Z: mapped to \\server\deploymentshare$]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Disconnecting drive Z: mapped to \\server\deploymentshare$]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Cleaning up C:\MININT directory.]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup"> <![LOG[Cleaning up TOOLS, SCRIPTS, and PACKAGES directories.]LOG]!><time="11:48:36.000+000" date="07-25-2012" component="LTICleanup" context="" type="1" thread="" file="LTICleanup">

    Read the article

  • Python Permutation Program Flow help

    - by dsaccount1
    Hello world, i found this code at activestate, it takes a string and prints permutations of the string. I understand that its a recursive function but i dont really understand how it works, it'd be great if someone could walk me through the program flow, thanks a bunch! <pre><code> import sys def printList(alist, blist=[]): if not len(alist): print ''.join(blist) for i in range(len(alist)): blist.append(alist.pop(i)) printList(alist, blist) alist.insert(i, blist.pop()) if name == 'main': k='love' if len(sys.argv)1: k = sys.argv[1] printList(list(k))

    Read the article

  • SSIS Data Flow Task SQL 2008

    - by Gerard
    Hi All, I am wondering if it is possible to: 1) Develop SSIS Package for Data Flow Task I am aware of how to do this on a local or network SQLServer, However is it possible to create a package that uploads to a "remote" sqlserver, ie one that is not on site or on the LAN. any guidance would be great Thanks

    Read the article

  • MVC model flow?

    - by fuzzygoat
    I am setting up an application using the MVC model and I have a query regrading the flow of information from the UI to the data model. What I need to do is place data from the UI in the model, what I have done is write a method in the view which collects the required data in an object and then passes it to the model. The model then takes ownership of the data so that the view can release its ownership. Does this sound sensible?

    Read the article

  • Best way to model Installation logic/flow

    - by Ian
    Hi All, We are currently working on designing the installer for our product. We are currently on the design phase and I'm wondering what is the best diagram (UML or not) to use when modeling installation logic or flow? Currently, we are using the good'ol flowchart. Thanks!

    Read the article

  • ParallelWork: Feature rich multithreaded fluent task execution library for WPF

    - by oazabir
    ParallelWork is an open source free helper class that lets you run multiple work in parallel threads, get success, failure and progress update on the WPF UI thread, wait for work to complete, abort all work (in case of shutdown), queue work to run after certain time, chain parallel work one after another. It’s more convenient than using .NET’s BackgroundWorker because you don’t have to declare one component per work, nor do you need to declare event handlers to receive notification and carry additional data through private variables. You can safely pass objects produced from different thread to the success callback. Moreover, you can wait for work to complete before you do certain operation and you can abort all parallel work while they are in-flight. If you are building highly responsive WPF UI where you have to carry out multiple job in parallel yet want full control over those parallel jobs completion and cancellation, then the ParallelWork library is the right solution for you. I am using the ParallelWork library in my PlantUmlEditor project, which is a free open source UML editor built on WPF. You can see some realistic use of the ParallelWork library there. Moreover, the test project comes with 400 lines of Behavior Driven Development flavored tests, that confirms it really does what it says it does. The source code of the library is part of the “Utilities” project in PlantUmlEditor source code hosted at Google Code. The library comes in two flavors, one is the ParallelWork static class, which has a collection of static methods that you can call. Another is the Start class, which is a fluent wrapper over the ParallelWork class to make it more readable and aesthetically pleasing code. ParallelWork allows you to start work immediately on separate thread or you can queue a work to start after some duration. You can start an immediate work in a new thread using the following methods: void StartNow(Action doWork, Action onComplete) void StartNow(Action doWork, Action onComplete, Action<Exception> failed) For example, ParallelWork.StartNow(() => { workStartedAt = DateTime.Now; Thread.Sleep(howLongWorkTakes); }, () => { workEndedAt = DateTime.Now; }); Or you can use the fluent way Start.Work: Start.Work(() => { workStartedAt = DateTime.Now; Thread.Sleep(howLongWorkTakes); }) .OnComplete(() => { workCompletedAt = DateTime.Now; }) .Run(); Besides simple execution of work on a parallel thread, you can have the parallel thread produce some object and then pass it to the success callback by using these overloads: void StartNow<T>(Func<T> doWork, Action<T> onComplete) void StartNow<T>(Func<T> doWork, Action<T> onComplete, Action<Exception> fail) For example, ParallelWork.StartNow<Dictionary<string, string>>( () => { test = new Dictionary<string,string>(); test.Add("test", "test"); return test; }, (result) => { Assert.True(result.ContainsKey("test")); }); Or, the fluent way: Start<Dictionary<string, string>>.Work(() => { test = new Dictionary<string, string>(); test.Add("test", "test"); return test; }) .OnComplete((result) => { Assert.True(result.ContainsKey("test")); }) .Run(); You can also start a work to happen after some time using these methods: DispatcherTimer StartAfter(Action onComplete, TimeSpan duration) DispatcherTimer StartAfter(Action doWork,Action onComplete,TimeSpan duration) You can use this to perform some timed operation on the UI thread, as well as perform some operation in separate thread after some time. ParallelWork.StartAfter( () => { workStartedAt = DateTime.Now; Thread.Sleep(howLongWorkTakes); }, () => { workCompletedAt = DateTime.Now; }, waitDuration); Or, the fluent way: Start.Work(() => { workStartedAt = DateTime.Now; Thread.Sleep(howLongWorkTakes); }) .OnComplete(() => { workCompletedAt = DateTime.Now; }) .RunAfter(waitDuration);   There are several overloads of these functions to have a exception callback for handling exceptions or get progress update from background thread while work is in progress. For example, I use it in my PlantUmlEditor to perform background update of the application. // Check if there's a newer version of the app Start<bool>.Work(() => { return UpdateChecker.HasUpdate(Settings.Default.DownloadUrl); }) .OnComplete((hasUpdate) => { if (hasUpdate) { if (MessageBox.Show(Window.GetWindow(me), "There's a newer version available. Do you want to download and install?", "New version available", MessageBoxButton.YesNo, MessageBoxImage.Information) == MessageBoxResult.Yes) { ParallelWork.StartNow(() => { var tempPath = System.IO.Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Settings.Default.SetupExeName); UpdateChecker.DownloadLatestUpdate(Settings.Default.DownloadUrl, tempPath); }, () => { }, (x) => { MessageBox.Show(Window.GetWindow(me), "Download failed. When you run next time, it will try downloading again.", "Download failed", MessageBoxButton.OK, MessageBoxImage.Warning); }); } } }) .OnException((x) => { MessageBox.Show(Window.GetWindow(me), x.Message, "Download failed", MessageBoxButton.OK, MessageBoxImage.Exclamation); }); The above code shows you how to get exception callbacks on the UI thread so that you can take necessary actions on the UI. Moreover, it shows how you can chain two parallel works to happen one after another. Sometimes you want to do some parallel work when user does some activity on the UI. For example, you might want to save file in an editor while user is typing every 10 second. In such case, you need to make sure you don’t start another parallel work every 10 seconds while a work is already queued. You need to make sure you start a new work only when there’s no other background work going on. Here’s how you can do it: private void ContentEditor_TextChanged(object sender, EventArgs e) { if (!ParallelWork.IsAnyWorkRunning()) { ParallelWork.StartAfter(SaveAndRefreshDiagram, TimeSpan.FromSeconds(10)); } } If you want to shutdown your application and want to make sure no parallel work is going on, then you can call the StopAll() method. ParallelWork.StopAll(); If you want to wait for parallel works to complete without a timeout, then you can call the WaitForAllWork(TimeSpan timeout). It will block the current thread until the all parallel work completes or the timeout period elapses. result = ParallelWork.WaitForAllWork(TimeSpan.FromSeconds(1)); The result is true, if all parallel work completed. If it’s false, then the timeout period elapsed and all parallel work did not complete. For details how this library is built and how it works, please read the following codeproject article: ParallelWork: Feature rich multithreaded fluent task execution library for WPF http://www.codeproject.com/KB/WPF/parallelwork.aspx If you like the article, please vote for me.

    Read the article

  • SSW Scrum Rule: Do you know to use clear task descriptions?

    - by Martin Hinshelwood
    When you create tasks in Scrum you are doing this within a time box and you tend to add only the information you need to remember what the task is. And the entire Team was at the meeting and were involved in the discussions around the task, so why do you need more? Once you have accepted a task you should then add as much information as possible so that anyone can pick up that task; what if your numbers come up? Will you be into work the next day? Figure: What if your numbers come up in the lottery? What if the Team runs a syndicate and all your numbers come up? The point is that anything can happen and you need to protect the integrity of the project, the company and the Customer. Add as much information to the task as you think is necessary for anyone to work on the task. If you need to add rich text and images you can do this by attaching an email to the task.   Figure: Bad example, there is not enough information for a non team member to complete this task Figure: Julie provided a lot more information and another team should be able to pick this up. This has been published as Do you know to ensure that relevant emails are attached to tasks in our Rules to Better Scrum using TFS.   Technorati Tags: Scrum,SSW Rules,TFS 2010

    Read the article

  • Understanding C# async / await (1) Compilation

    - by Dixin
    Now the async / await keywords are in C#. Just like the async and ! in F#, this new C# feature provides great convenience. There are many nice documents talking about how to use async / await in specific scenarios, like using async methods in ASP.NET 4.5 and in ASP.NET MVC 4, etc. In this article we will look at the real code working behind the syntax sugar. According to MSDN: The async modifier indicates that the method, lambda expression, or anonymous method that it modifies is asynchronous. Since lambda expression / anonymous method will be compiled to normal method, we will focus on normal async method. Preparation First of all, Some helper methods need to make up. internal class HelperMethods { internal static int Method(int arg0, int arg1) { // Do some IO. WebClient client = new WebClient(); Enumerable.Repeat("http://weblogs.asp.net/dixin", 10) .Select(client.DownloadString).ToArray(); int result = arg0 + arg1; return result; } internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; } internal static void Before() { } internal static void Continuation1(int arg) { } internal static void Continuation2(int arg) { } } Here Method() is a long running method doing some IO. Then MethodTask() wraps it into a Task and return that Task. Nothing special here. Await something in async method Since MethodTask() returns Task, let’s try to await it: internal class AsyncMethods { internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; } } Because we used await in the method, async must be put on the method. Now we get the first async method. According to the naming convenience, it is called MethodAsync. Of course a async method can be awaited. So we have a CallMethodAsync() to call MethodAsync(): internal class AsyncMethods { internal static async Task<int> CallMethodAsync(int arg0, int arg1) { int result = await MethodAsync(arg0, arg1); return result; } } After compilation, MethodAsync() and CallMethodAsync() becomes the same logic. This is the code of MethodAsyc(): internal class CompiledAsyncMethods { [DebuggerStepThrough] [AsyncStateMachine(typeof(MethodAsyncStateMachine))] // async internal static /*async*/ Task<int> MethodAsync(int arg0, int arg1) { MethodAsyncStateMachine methodAsyncStateMachine = new MethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Builder = AsyncTaskMethodBuilder<int>.Create(), State = -1 }; methodAsyncStateMachine.Builder.Start(ref methodAsyncStateMachine); return methodAsyncStateMachine.Builder.Task; } } It just creates and starts a state machine MethodAsyncStateMachine: [CompilerGenerated] [StructLayout(LayoutKind.Auto)] internal struct MethodAsyncStateMachine : IAsyncStateMachine { public int State; public AsyncTaskMethodBuilder<int> Builder; public int Arg0; public int Arg1; public int Result; private TaskAwaiter<int> awaitor; void IAsyncStateMachine.MoveNext() { try { if (this.State != 0) { this.awaitor = HelperMethods.MethodTask(this.Arg0, this.Arg1).GetAwaiter(); if (!this.awaitor.IsCompleted) { this.State = 0; this.Builder.AwaitUnsafeOnCompleted(ref this.awaitor, ref this); return; } } else { this.State = -1; } this.Result = this.awaitor.GetResult(); } catch (Exception exception) { this.State = -2; this.Builder.SetException(exception); return; } this.State = -2; this.Builder.SetResult(this.Result); } [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine param0) { this.Builder.SetStateMachine(param0); } } The generated code has been cleaned up so it is readable and can be compiled. Several things can be observed here: The async modifier is gone, which shows, unlike other modifiers (e.g. static), there is no such IL/CLR level “async” stuff. It becomes a AsyncStateMachineAttribute. This is similar to the compilation of extension method. The generated state machine is very similar to the state machine of C# yield syntax sugar. The local variables (arg0, arg1, result) are compiled to fields of the state machine. The real code (await HelperMethods.MethodTask(arg0, arg1)) is compiled into MoveNext(): HelperMethods.MethodTask(this.Arg0, this.Arg1).GetAwaiter(). CallMethodAsync() will create and start its own state machine CallMethodAsyncStateMachine: internal class CompiledAsyncMethods { [DebuggerStepThrough] [AsyncStateMachine(typeof(CallMethodAsyncStateMachine))] // async internal static /*async*/ Task<int> CallMethodAsync(int arg0, int arg1) { CallMethodAsyncStateMachine callMethodAsyncStateMachine = new CallMethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Builder = AsyncTaskMethodBuilder<int>.Create(), State = -1 }; callMethodAsyncStateMachine.Builder.Start(ref callMethodAsyncStateMachine); return callMethodAsyncStateMachine.Builder.Task; } } CallMethodAsyncStateMachine has the same logic as MethodAsyncStateMachine above. The detail of the state machine will be discussed soon. Now it is clear that: async /await is a C# level syntax sugar. There is no difference to await a async method or a normal method. A method returning Task will be awaitable. State machine and continuation To demonstrate more details in the state machine, a more complex method is created: internal class AsyncMethods { internal static async Task<int> MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3) { HelperMethods.Before(); int resultOfAwait1 = await MethodAsync(arg0, arg1); HelperMethods.Continuation1(resultOfAwait1); int resultOfAwait2 = await MethodAsync(arg2, arg3); HelperMethods.Continuation2(resultOfAwait2); int resultToReturn = resultOfAwait1 + resultOfAwait2; return resultToReturn; } } In this method: There are multiple awaits. There are code before the awaits, and continuation code after each await After compilation, this multi-await method becomes the same as above single-await methods: internal class CompiledAsyncMethods { [DebuggerStepThrough] [AsyncStateMachine(typeof(MultiCallMethodAsyncStateMachine))] // async internal static /*async*/ Task<int> MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3) { MultiCallMethodAsyncStateMachine multiCallMethodAsyncStateMachine = new MultiCallMethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Arg2 = arg2, Arg3 = arg3, Builder = AsyncTaskMethodBuilder<int>.Create(), State = -1 }; multiCallMethodAsyncStateMachine.Builder.Start(ref multiCallMethodAsyncStateMachine); return multiCallMethodAsyncStateMachine.Builder.Task; } } It creates and starts one single state machine, MultiCallMethodAsyncStateMachine: [CompilerGenerated] [StructLayout(LayoutKind.Auto)] internal struct MultiCallMethodAsyncStateMachine : IAsyncStateMachine { public int State; public AsyncTaskMethodBuilder<int> Builder; public int Arg0; public int Arg1; public int Arg2; public int Arg3; public int ResultOfAwait1; public int ResultOfAwait2; public int ResultToReturn; private TaskAwaiter<int> awaiter; void IAsyncStateMachine.MoveNext() { try { switch (this.State) { case -1: HelperMethods.Before(); this.awaiter = AsyncMethods.MethodAsync(this.Arg0, this.Arg1).GetAwaiter(); if (!this.awaiter.IsCompleted) { this.State = 0; this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this); } break; case 0: this.ResultOfAwait1 = this.awaiter.GetResult(); HelperMethods.Continuation1(this.ResultOfAwait1); this.awaiter = AsyncMethods.MethodAsync(this.Arg2, this.Arg3).GetAwaiter(); if (!this.awaiter.IsCompleted) { this.State = 1; this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this); } break; case 1: this.ResultOfAwait2 = this.awaiter.GetResult(); HelperMethods.Continuation2(this.ResultOfAwait2); this.ResultToReturn = this.ResultOfAwait1 + this.ResultOfAwait2; this.State = -2; this.Builder.SetResult(this.ResultToReturn); break; } } catch (Exception exception) { this.State = -2; this.Builder.SetException(exception); } } [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { this.Builder.SetStateMachine(stateMachine); } } The above code is already cleaned up, but there are still a lot of things. More clean up can be done, and the state machine can be very simple: [CompilerGenerated] [StructLayout(LayoutKind.Auto)] internal struct MultiCallMethodAsyncStateMachine : IAsyncStateMachine { // State: // -1: Begin // 0: 1st await is done // 1: 2nd await is done // ... // -2: End public int State; public TaskCompletionSource<int> ResultToReturn; // int resultToReturn ... public int Arg0; // int Arg0 public int Arg1; // int arg1 public int Arg2; // int arg2 public int Arg3; // int arg3 public int ResultOfAwait1; // int resultOfAwait1 ... public int ResultOfAwait2; // int resultOfAwait2 ... private Task<int> currentTaskToAwait; /// <summary> /// Moves the state machine to its next state. /// </summary> void IAsyncStateMachine.MoveNext() { try { switch (this.State) { // Orginal code is splitted by "case"s: // case -1: // HelperMethods.Before(); // MethodAsync(Arg0, arg1); // case 0: // int resultOfAwait1 = await ... // HelperMethods.Continuation1(resultOfAwait1); // MethodAsync(arg2, arg3); // case 1: // int resultOfAwait2 = await ... // HelperMethods.Continuation2(resultOfAwait2); // int resultToReturn = resultOfAwait1 + resultOfAwait2; // return resultToReturn; case -1: // -1 is begin. HelperMethods.Before(); // Code before 1st await. this.currentTaskToAwait = AsyncMethods.MethodAsync(this.Arg0, this.Arg1); // 1st task to await // When this.currentTaskToAwait is done, run this.MoveNext() and go to case 0. this.State = 0; IAsyncStateMachine this1 = this; // Cannot use "this" in lambda so create a local variable. this.currentTaskToAwait.ContinueWith(_ => this1.MoveNext()); // Callback break; case 0: // Now 1st await is done. this.ResultOfAwait1 = this.currentTaskToAwait.Result; // Get 1st await's result. HelperMethods.Continuation1(this.ResultOfAwait1); // Code after 1st await and before 2nd await. this.currentTaskToAwait = AsyncMethods.MethodAsync(this.Arg2, this.Arg3); // 2nd task to await // When this.currentTaskToAwait is done, run this.MoveNext() and go to case 1. this.State = 1; IAsyncStateMachine this2 = this; // Cannot use "this" in lambda so create a local variable. this.currentTaskToAwait.ContinueWith(_ => this2.MoveNext()); // Callback break; case 1: // Now 2nd await is done. this.ResultOfAwait2 = this.currentTaskToAwait.Result; // Get 2nd await's result. HelperMethods.Continuation2(this.ResultOfAwait2); // Code after 2nd await. int resultToReturn = this.ResultOfAwait1 + this.ResultOfAwait2; // Code after 2nd await. // End with resultToReturn. this.State = -2; // -2 is end. this.ResultToReturn.SetResult(resultToReturn); break; } } catch (Exception exception) { // End with exception. this.State = -2; // -2 is end. this.ResultToReturn.SetException(exception); } } /// <summary> /// Configures the state machine with a heap-allocated replica. /// </summary> /// <param name="stateMachine">The heap-allocated replica.</param> [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { // No core logic. } } Only Task and TaskCompletionSource are involved in this version. And MultiCallMethodAsync() can be simplified to: [DebuggerStepThrough] [AsyncStateMachine(typeof(MultiCallMethodAsyncStateMachine))] // async internal static /*async*/ Task<int> MultiCallMethodAsync_(int arg0, int arg1, int arg2, int arg3) { MultiCallMethodAsyncStateMachine multiCallMethodAsyncStateMachine = new MultiCallMethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Arg2 = arg2, Arg3 = arg3, ResultToReturn = new TaskCompletionSource<int>(), // -1: Begin // 0: 1st await is done // 1: 2nd await is done // ... // -2: End State = -1 }; (multiCallMethodAsyncStateMachine as IAsyncStateMachine).MoveNext(); // Original code are in this method. return multiCallMethodAsyncStateMachine.ResultToReturn.Task; } Now the whole state machine becomes very clear - it is about callback: Original code are split into pieces by “await”s, and each piece is put into each “case” in the state machine. Here the 2 awaits split the code into 3 pieces, so there are 3 “case”s. The “piece”s are chained by callback, that is done by Builder.AwaitUnsafeOnCompleted(callback), or currentTaskToAwait.ContinueWith(callback) in the simplified code. A previous “piece” will end with a Task (which is to be awaited), when the task is done, it will callback the next “piece”. The state machine’s state works with the “case”s to ensure the code “piece”s executes one after another. Callback Since it is about callback, the simplification  can go even further – the entire state machine can be completely purged. Now MultiCallMethodAsync() becomes: internal static Task<int> MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3) { TaskCompletionSource<int> taskCompletionSource = new TaskCompletionSource<int>(); try { // Oringinal code begins. HelperMethods.Before(); MethodAsync(arg0, arg1).ContinueWith(await1 => { int resultOfAwait1 = await1.Result; HelperMethods.Continuation1(resultOfAwait1); MethodAsync(arg2, arg3).ContinueWith(await2 => { int resultOfAwait2 = await2.Result; HelperMethods.Continuation2(resultOfAwait2); int resultToReturn = resultOfAwait1 + resultOfAwait2; // Oringinal code ends. taskCompletionSource.SetResult(resultToReturn); }); }); } catch (Exception exception) { taskCompletionSource.SetException(exception); } return taskCompletionSource.Task; } Please compare with the original async / await code: HelperMethods.Before(); int resultOfAwait1 = await MethodAsync(arg0, arg1); HelperMethods.Continuation1(resultOfAwait1); int resultOfAwait2 = await MethodAsync(arg2, arg3); HelperMethods.Continuation2(resultOfAwait2); int resultToReturn = resultOfAwait1 + resultOfAwait2; return resultToReturn; Yeah that is the magic of C# async / await: Await is literally pretending to wait. In a await expression, a Task object will be return immediately so that caller is not blocked. The continuation code is compiled as that Task’s callback code. When that task is done, continuation code will execute. Please notice that many details inside the state machine are omitted for simplicity, like context caring, etc. If you want to have a detailed picture, please do check out the source code of AsyncTaskMethodBuilder and TaskAwaiter.

    Read the article

  • Understanding C# async / await (1) Compilation

    - by Dixin
    Now the async / await keywords are in C#. Just like the async and ! in F#, this new C# feature provides great convenience. There are many nice documents talking about how to use async / await in specific scenarios, like using async methods in ASP.NET 4.5 and in ASP.NET MVC 4, etc. In this article we will look at the real code working behind the syntax sugar. According to MSDN: The async modifier indicates that the method, lambda expression, or anonymous method that it modifies is asynchronous. Since lambda expression / anonymous method will be compiled to normal method, we will focus on normal async method. Preparation First of all, Some helper methods need to make up. internal class HelperMethods { internal static int Method(int arg0, int arg1) { // Do some IO. WebClient client = new WebClient(); Enumerable.Repeat("http://weblogs.asp.net/dixin", 10) .Select(client.DownloadString).ToArray(); int result = arg0 + arg1; return result; } internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; } internal static void Before() { } internal static void Continuation1(int arg) { } internal static void Continuation2(int arg) { } } Here Method() is a long running method doing some IO. Then MethodTask() wraps it into a Task and return that Task. Nothing special here. Await something in async method Since MethodTask() returns Task, let’s try to await it: internal class AsyncMethods { internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; } } Because we used await in the method, async must be put on the method. Now we get the first async method. According to the naming convenience, it is named MethodAsync. Of course a async method can be awaited. So we have a CallMethodAsync() to call MethodAsync(): internal class AsyncMethods { internal static async Task<int> CallMethodAsync(int arg0, int arg1) { int result = await MethodAsync(arg0, arg1); return result; } } After compilation, MethodAsync() and CallMethodAsync() becomes the same logic. This is the code of MethodAsyc(): internal class CompiledAsyncMethods { [DebuggerStepThrough] [AsyncStateMachine(typeof(MethodAsyncStateMachine))] // async internal static /*async*/ Task<int> MethodAsync(int arg0, int arg1) { MethodAsyncStateMachine methodAsyncStateMachine = new MethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Builder = AsyncTaskMethodBuilder<int>.Create(), State = -1 }; methodAsyncStateMachine.Builder.Start(ref methodAsyncStateMachine); return methodAsyncStateMachine.Builder.Task; } } It just creates and starts a state machine, MethodAsyncStateMachine: [CompilerGenerated] [StructLayout(LayoutKind.Auto)] internal struct MethodAsyncStateMachine : IAsyncStateMachine { public int State; public AsyncTaskMethodBuilder<int> Builder; public int Arg0; public int Arg1; public int Result; private TaskAwaiter<int> awaitor; void IAsyncStateMachine.MoveNext() { try { if (this.State != 0) { this.awaitor = HelperMethods.MethodTask(this.Arg0, this.Arg1).GetAwaiter(); if (!this.awaitor.IsCompleted) { this.State = 0; this.Builder.AwaitUnsafeOnCompleted(ref this.awaitor, ref this); return; } } else { this.State = -1; } this.Result = this.awaitor.GetResult(); } catch (Exception exception) { this.State = -2; this.Builder.SetException(exception); return; } this.State = -2; this.Builder.SetResult(this.Result); } [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine param0) { this.Builder.SetStateMachine(param0); } } The generated code has been refactored, so it is readable and can be compiled. Several things can be observed here: The async modifier is gone, which shows, unlike other modifiers (e.g. static), there is no such IL/CLR level “async” stuff. It becomes a AsyncStateMachineAttribute. This is similar to the compilation of extension method. The generated state machine is very similar to the state machine of C# yield syntax sugar. The local variables (arg0, arg1, result) are compiled to fields of the state machine. The real code (await HelperMethods.MethodTask(arg0, arg1)) is compiled into MoveNext(): HelperMethods.MethodTask(this.Arg0, this.Arg1).GetAwaiter(). CallMethodAsync() will create and start its own state machine CallMethodAsyncStateMachine: internal class CompiledAsyncMethods { [DebuggerStepThrough] [AsyncStateMachine(typeof(CallMethodAsyncStateMachine))] // async internal static /*async*/ Task<int> CallMethodAsync(int arg0, int arg1) { CallMethodAsyncStateMachine callMethodAsyncStateMachine = new CallMethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Builder = AsyncTaskMethodBuilder<int>.Create(), State = -1 }; callMethodAsyncStateMachine.Builder.Start(ref callMethodAsyncStateMachine); return callMethodAsyncStateMachine.Builder.Task; } } CallMethodAsyncStateMachine has the same logic as MethodAsyncStateMachine above. The detail of the state machine will be discussed soon. Now it is clear that: async /await is a C# language level syntax sugar. There is no difference to await a async method or a normal method. As long as a method returns Task, it is awaitable. State machine and continuation To demonstrate more details in the state machine, a more complex method is created: internal class AsyncMethods { internal static async Task<int> MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3) { HelperMethods.Before(); int resultOfAwait1 = await MethodAsync(arg0, arg1); HelperMethods.Continuation1(resultOfAwait1); int resultOfAwait2 = await MethodAsync(arg2, arg3); HelperMethods.Continuation2(resultOfAwait2); int resultToReturn = resultOfAwait1 + resultOfAwait2; return resultToReturn; } } In this method: There are multiple awaits. There are code before the awaits, and continuation code after each await After compilation, this multi-await method becomes the same as above single-await methods: internal class CompiledAsyncMethods { [DebuggerStepThrough] [AsyncStateMachine(typeof(MultiCallMethodAsyncStateMachine))] // async internal static /*async*/ Task<int> MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3) { MultiCallMethodAsyncStateMachine multiCallMethodAsyncStateMachine = new MultiCallMethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Arg2 = arg2, Arg3 = arg3, Builder = AsyncTaskMethodBuilder<int>.Create(), State = -1 }; multiCallMethodAsyncStateMachine.Builder.Start(ref multiCallMethodAsyncStateMachine); return multiCallMethodAsyncStateMachine.Builder.Task; } } It creates and starts one single state machine, MultiCallMethodAsyncStateMachine: [CompilerGenerated] [StructLayout(LayoutKind.Auto)] internal struct MultiCallMethodAsyncStateMachine : IAsyncStateMachine { public int State; public AsyncTaskMethodBuilder<int> Builder; public int Arg0; public int Arg1; public int Arg2; public int Arg3; public int ResultOfAwait1; public int ResultOfAwait2; public int ResultToReturn; private TaskAwaiter<int> awaiter; void IAsyncStateMachine.MoveNext() { try { switch (this.State) { case -1: HelperMethods.Before(); this.awaiter = AsyncMethods.MethodAsync(this.Arg0, this.Arg1).GetAwaiter(); if (!this.awaiter.IsCompleted) { this.State = 0; this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this); } break; case 0: this.ResultOfAwait1 = this.awaiter.GetResult(); HelperMethods.Continuation1(this.ResultOfAwait1); this.awaiter = AsyncMethods.MethodAsync(this.Arg2, this.Arg3).GetAwaiter(); if (!this.awaiter.IsCompleted) { this.State = 1; this.Builder.AwaitUnsafeOnCompleted(ref this.awaiter, ref this); } break; case 1: this.ResultOfAwait2 = this.awaiter.GetResult(); HelperMethods.Continuation2(this.ResultOfAwait2); this.ResultToReturn = this.ResultOfAwait1 + this.ResultOfAwait2; this.State = -2; this.Builder.SetResult(this.ResultToReturn); break; } } catch (Exception exception) { this.State = -2; this.Builder.SetException(exception); } } [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { this.Builder.SetStateMachine(stateMachine); } } Once again, the above state machine code is already refactored, but it still has a lot of things. More clean up can be done if we only keep the core logic, and the state machine can become very simple: [CompilerGenerated] [StructLayout(LayoutKind.Auto)] internal struct MultiCallMethodAsyncStateMachine : IAsyncStateMachine { // State: // -1: Begin // 0: 1st await is done // 1: 2nd await is done // ... // -2: End public int State; public TaskCompletionSource<int> ResultToReturn; // int resultToReturn ... public int Arg0; // int Arg0 public int Arg1; // int arg1 public int Arg2; // int arg2 public int Arg3; // int arg3 public int ResultOfAwait1; // int resultOfAwait1 ... public int ResultOfAwait2; // int resultOfAwait2 ... private Task<int> currentTaskToAwait; /// <summary> /// Moves the state machine to its next state. /// </summary> public void MoveNext() // IAsyncStateMachine member. { try { switch (this.State) { // Original code is split by "await"s into "case"s: // case -1: // HelperMethods.Before(); // MethodAsync(Arg0, arg1); // case 0: // int resultOfAwait1 = await ... // HelperMethods.Continuation1(resultOfAwait1); // MethodAsync(arg2, arg3); // case 1: // int resultOfAwait2 = await ... // HelperMethods.Continuation2(resultOfAwait2); // int resultToReturn = resultOfAwait1 + resultOfAwait2; // return resultToReturn; case -1: // -1 is begin. HelperMethods.Before(); // Code before 1st await. this.currentTaskToAwait = AsyncMethods.MethodAsync(this.Arg0, this.Arg1); // 1st task to await // When this.currentTaskToAwait is done, run this.MoveNext() and go to case 0. this.State = 0; MultiCallMethodAsyncStateMachine that1 = this; // Cannot use "this" in lambda so create a local variable. this.currentTaskToAwait.ContinueWith(_ => that1.MoveNext()); break; case 0: // Now 1st await is done. this.ResultOfAwait1 = this.currentTaskToAwait.Result; // Get 1st await's result. HelperMethods.Continuation1(this.ResultOfAwait1); // Code after 1st await and before 2nd await. this.currentTaskToAwait = AsyncMethods.MethodAsync(this.Arg2, this.Arg3); // 2nd task to await // When this.currentTaskToAwait is done, run this.MoveNext() and go to case 1. this.State = 1; MultiCallMethodAsyncStateMachine that2 = this; this.currentTaskToAwait.ContinueWith(_ => that2.MoveNext()); break; case 1: // Now 2nd await is done. this.ResultOfAwait2 = this.currentTaskToAwait.Result; // Get 2nd await's result. HelperMethods.Continuation2(this.ResultOfAwait2); // Code after 2nd await. int resultToReturn = this.ResultOfAwait1 + this.ResultOfAwait2; // Code after 2nd await. // End with resultToReturn. this.State = -2; // -2 is end. this.ResultToReturn.SetResult(resultToReturn); break; } } catch (Exception exception) { // End with exception. this.State = -2; // -2 is end. this.ResultToReturn.SetException(exception); } } /// <summary> /// Configures the state machine with a heap-allocated replica. /// </summary> /// <param name="stateMachine">The heap-allocated replica.</param> [DebuggerHidden] public void SetStateMachine(IAsyncStateMachine stateMachine) // IAsyncStateMachine member. { // No core logic. } } Only Task and TaskCompletionSource are involved in this version. And MultiCallMethodAsync() can be simplified to: [DebuggerStepThrough] [AsyncStateMachine(typeof(MultiCallMethodAsyncStateMachine))] // async internal static /*async*/ Task<int> MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3) { MultiCallMethodAsyncStateMachine multiCallMethodAsyncStateMachine = new MultiCallMethodAsyncStateMachine() { Arg0 = arg0, Arg1 = arg1, Arg2 = arg2, Arg3 = arg3, ResultToReturn = new TaskCompletionSource<int>(), // -1: Begin // 0: 1st await is done // 1: 2nd await is done // ... // -2: End State = -1 }; multiCallMethodAsyncStateMachine.MoveNext(); // Original code are moved into this method. return multiCallMethodAsyncStateMachine.ResultToReturn.Task; } Now the whole state machine becomes very clean - it is about callback: Original code are split into pieces by “await”s, and each piece is put into each “case” in the state machine. Here the 2 awaits split the code into 3 pieces, so there are 3 “case”s. The “piece”s are chained by callback, that is done by Builder.AwaitUnsafeOnCompleted(callback), or currentTaskToAwait.ContinueWith(callback) in the simplified code. A previous “piece” will end with a Task (which is to be awaited), when the task is done, it will callback the next “piece”. The state machine’s state works with the “case”s to ensure the code “piece”s executes one after another. Callback If we focus on the point of callback, the simplification  can go even further – the entire state machine can be completely purged, and we can just keep the code inside MoveNext(). Now MultiCallMethodAsync() becomes: internal static Task<int> MultiCallMethodAsync(int arg0, int arg1, int arg2, int arg3) { TaskCompletionSource<int> taskCompletionSource = new TaskCompletionSource<int>(); try { // Oringinal code begins. HelperMethods.Before(); MethodAsync(arg0, arg1).ContinueWith(await1 => { int resultOfAwait1 = await1.Result; HelperMethods.Continuation1(resultOfAwait1); MethodAsync(arg2, arg3).ContinueWith(await2 => { int resultOfAwait2 = await2.Result; HelperMethods.Continuation2(resultOfAwait2); int resultToReturn = resultOfAwait1 + resultOfAwait2; // Oringinal code ends. taskCompletionSource.SetResult(resultToReturn); }); }); } catch (Exception exception) { taskCompletionSource.SetException(exception); } return taskCompletionSource.Task; } Please compare with the original async / await code: HelperMethods.Before(); int resultOfAwait1 = await MethodAsync(arg0, arg1); HelperMethods.Continuation1(resultOfAwait1); int resultOfAwait2 = await MethodAsync(arg2, arg3); HelperMethods.Continuation2(resultOfAwait2); int resultToReturn = resultOfAwait1 + resultOfAwait2; return resultToReturn; Yeah that is the magic of C# async / await: Await is not to wait. In a await expression, a Task object will be return immediately so that execution is not blocked. The continuation code is compiled as that Task’s callback code. When that task is done, continuation code will execute. Please notice that many details inside the state machine are omitted for simplicity, like context caring, etc. If you want to have a detailed picture, please do check out the source code of AsyncTaskMethodBuilder and TaskAwaiter.

    Read the article

  • UI Design Patterns : Are you developing a Fusion Apps extension, an ADF or Webcenter App?

    - by asantaga
    A big question I get asked when speaking to partners who are developing Oracle ADF, or Webcenter, Apps is how to make it look nice.. Some of the big SIs ask me, "Do we have any design patterns/guidelines we can use?". .. Alas website design is a very personal thing and each website will have different requirements and needs, however I am now pleased to say we've just launched "Oracle Fusion Applications Design Patterns" website.   The website is the result of many years of Oracle R&D into user interface design for Fusion applications and features a really cool web app which allows you to visualise the UI components in action. Although many of the design patterns are related to ADF , its worth noting that ADF took its lead from Oracle Fusion Applications User Interface needs - not the other way around, its just taken us a while to publish these. Coupled together with the dashboard patterns this makes are really cool extra asset for your kit bag Design Patterns Oracle dashboard patterns and guidelines Usable Apps.oracle.com Enjoy

    Read the article

  • Do you want to be an officially certified Oracle ADF Developer?

    - by Grant Ronald
    We have just released an official certification exam for Oracle ADF Development.  This exam is aimed that those who are already getting hands-on with ADF and would like an official certification of their development skills. I was involved in writing some of the exam questions and this was an interesting experience.  We were looking to test not only a knowledge of the framework, but also a practical application of that knowledge.  Trying to do that in a clear question which related to multiple choice questions was sometimes difficult but I think we’ve produced a testing exam which, if you pass, shows a strong practical knowledge of ADF. Enjoy!

    Read the article

  • Sorting and Filtering By Model-Based LOV Display Value

    - by Steven Davelaar
    If you use a model-based LOV and you use display type "choice", then ADF nicely displays the display value, even if the table is read-only. In the screen shot below, you see the RegionName attribute displayed instead of the RegionId. This is accomplished by the model-based LOV, I did not modify the Countries view object to include a join with Regions.  Also note the sort icon, the table is sorted by RegionId. This sorting typically results in a bug reported by your test team. Europe really shouldn't come before America when sorting ascending, right? To fix this, we could of course change the Countries view object query and add a join with the Regions table to include the RegionName attribute. If the table is updateable, we still need the choice list, so we need to move the model-based LOV from the RegionId attribute to the RegionName attribute and hide the RegionId attribute in the table. But that is a lot of work for such a simple requirement, in particular if we have lots of model-based choice lists in our view object. Fortunately, there is an easier way to do this, with some generic code in your view object base class that fixes this at once for all model-based choice lists that we have defined in our application. The trick is to override the method getSortCriteria() in the base view object class. By default, this method returns null because the sorting is done in the database through a SQL Order By clause. However, if the getSortCriteria method does return a sort criteria the framework will perform in memory sorting which is what we need to achieve sorting by region name. So, inside this method we need to evaluate the Order By clause, and if the order by column matches an attribute that has a model-based LOV choicelist defined with a display attribute that is different from the value attribute, we need to return a sort criterria. Here is the complete code of this method: public SortCriteria[] getSortCriteria() {   String orderBy = getOrderByClause();          if (orderBy!=null )   {     boolean descending = false;     if (orderBy.endsWith(" DESC"))      {       descending = true;       orderBy = orderBy.substring(0,orderBy.length()-5);     }     // extract column name, is part after the dot     int dotpos = orderBy.lastIndexOf(".");     String columnName = orderBy.substring(dotpos+1);     // loop over attributes and find matching attribute     AttributeDef orderByAttrDef = null;     for (AttributeDef attrDef : getAttributeDefs())     {       if (columnName.equals(attrDef.getColumnName()))       {         orderByAttrDef = attrDef;         break;       }     }     if (orderByAttrDef!=null && "choice".equals(orderByAttrDef.getProperty("CONTROLTYPE"))          && orderByAttrDef.getListBindingDef()!=null)     {       String orderbyAttr = orderByAttrDef.getName();       String[] displayAttrs = orderByAttrDef.getListBindingDef().getListDisplayAttrNames();       String[] listAttrs = orderByAttrDef.getListBindingDef().getListAttrNames();       // if first list display attributes is not the same as first list attribute, than the value       // displayed is different from the value copied back to the order by attribute, in which case we need to       // use our custom comparator       if (displayAttrs!=null && listAttrs!=null && displayAttrs.length>0 && !displayAttrs[0].equals(listAttrs[0]))       {                  SortCriteriaImpl sc1 = new SortCriteriaImpl(orderbyAttr, descending);         SortCriteria[] sc = new SortCriteriaImpl[]{sc1};         return sc;                           }     }     }   return super.getSortCriteria(); } If this method returns a sort criteria, then the framework will call the sort method on the view object. The sort method uses a Comparator object to determine the sequence in which the rows should be returned. This comparator is retrieved by calling the getRowComparator method on the view object. So, to ensure sorting by our display value, we need to override this method to return our custom comparator: public Comparator getRowComparator() {   return new LovDisplayAttributeRowComparator(getSortCriteria()); } The custom comparator class extends the default RowComparator class and overrides the method compareRows and looks up the choice display value to compare the two rows. The complete code of this class is included in the sample application.  With this code in place, clicking on the Region sort icon nicely sorts the countries by RegionName, as you can see below. When using the Query-By-Example table filter at the top of the table, you typically want to use the same choice list to filter the rows. One way to do that is documented in ADF code corner sample 16 - How To Customize the ADF Faces Table Filter.The solution in this sample is perfectly fine to use. This sample requires you to define a separate iterator binding and associated tree binding to populate the choice list in the table filter area using the af:iterator tag. You might be able to reuse the same LOV view object instance in this iterator binding that is used as view accessor for the model-bassed LOV. However, I have seen quite a few customers who have a generic LOV view object (mapped to one "refcodes" table) with the bind variable values set in the LOV view accessor. In such a scenario, some duplicate work is needed to get a dedicated view object instance with the correct bind variables that can be used in the iterator binding. Looking for ways to maximize reuse, wouldn't it be nice if we could just reuse our model-based LOV to populate this filter choice list? Well we can. Here are the basic steps: 1. Create an attribute list binding in the page definition that we can use to retrieve the list of SelectItems needed to populate the choice list <list StaticList="false" Uses="LOV_RegionId"               IterBinding="CountriesView1Iterator" id="RegionId"/>  We need this "current row" list binding because the implicit list binding used by the item in the table is not accessible outside a table row, we cannot use the expression #{row.bindings.RegionId} in the table filter facet. 2. Create a Map-style managed bean with the get method retrieving the list binding as key, and returning the list of SelectItems. To return this list, we take the list of selectItems contained by the list binding and replace the index number that is normally used as key value with the actual attribute value that is set by the choice list. Here is the code of the get method:  public Object get(Object key) {   if (key instanceof FacesCtrlListBinding)   {     // we need to cast to internal class FacesCtrlListBinding rather than JUCtrlListBinding to     // be able to call getItems method. To prevent this import, we could evaluate an EL expression     // to get the list of items     FacesCtrlListBinding lb = (FacesCtrlListBinding) key;     if (cachedFilterLists.containsKey(lb.getName()))     {       return cachedFilterLists.get(lb.getName());     }     List<SelectItem> items = (List<SelectItem>)lb.getItems();     if (items==null || items.size()==0)     {       return items;     }     List<SelectItem> newItems = new ArrayList<SelectItem>();     JUCtrlValueDef def = ((JUCtrlValueDef)lb.getDef());     String valueAttr = def.getFirstAttrName();     // the items list has an index number as value, we need to replace this with the actual     // value of the attribute that is copied back by the choice list     for (int i = 0; i < items.size(); i++)     {       SelectItem si = (SelectItem) items.get(i);       Object value = lb.getValueFromList(i);       if (value instanceof Row)       {         Row row = (Row) value;         si.setValue(row.getAttribute(valueAttr));                 }       else       {         // this is the "empty" row, set value to empty string so all rows will be returned         // as user no longer wants to filter on this attribute         si.setValue("");       }       newItems.add(si);     }     cachedFilterLists.put(lb.getName(), newItems);     return newItems;   }   return null; } Note that we added caching to speed up performance, and to handle the situation where table filters or search criteria are set such that no rows are retrieved in the table. When there are no rows, there is no current row and the getItems method on the list binding will return no items.  An alternative approach to create the list of SelectItems would be to retrieve the iterator binding from the list binding and loop over the rows in the iterator binding rowset. Then we wouldn't need the import of the ADF internal oracle.adfinternal.view.faces.model.binding.FacesCtrlListBinding class, but then we need to figure out the display attributes from the list binding definition, and possible separate them with a dash if multiple display attributes are defined in the LOV. Doable but less reuse and more work. 3. Inside the filter facet for the column create an af:selectOneChoice with the value property of the f:selectItems tag referencing the get method of the managed bean:  <f:facet name="filter">   <af:selectOneChoice id="soc0" autoSubmit="true"                       value="#{vs.filterCriteria.RegionId}">     <!-- attention: the RegionId list binding must be created manually in the page definition! -->                       <f:selectItems id="si0"                    value="#{viewScope.TableFilterChoiceList[bindings.RegionId]}"/>   </af:selectOneChoice> </f:facet> Note that the managed bean is defined in viewScope for the caching to take effect. Here is a screen shot of the tabe filter in action: You can download the sample application here. 

    Read the article

  • An Epic Question "How to call a method when the page loads"

    - by Arunkumar Ramamoorthy
    Quite often, there comes a question in OTN, with different subjects, all meaning "How to call a method when my ADF page loads?". More often, people tend to take the approach of ADF Phase Listener by overriding before/afterPhase methods.In this blog, we will go through different options in achieving it.1. Method Call Activity as default activity in Taskflow :If the application is built with taskflows, then this is the best suited approach to take. 1.a. Calling a Data Control Method :To call a Data Control method (ex: A method in AMImpl exposed as client interface), simply Drag and Drop the method as Default Method Call Activity, then draw a control flow case from the method to your page. Once after this, drop the taskflow as region in main page. When we run the main page, the Method Call Activity would be called first, and then the page will be rendered.1.b. Calling a Method in Backing Bean: To call a method in the backing bean before pageload, we can follow the similar approach as above. Instead of binding the Method Call Activity to an action/method binding in pagedef, we bind to the method. Insert a Method Call Activity (and make it as default) from the Component Palette. Double click on to select a method to bind. This approach can also be used, to perform some action in backing bean along with calling a method Data Control (just need to add bindings code in backing bean to execute DC method). 2. Using invokeAction Executable :If the application is built with pages and no taskflows are involved, then this option can be taken into consideration.In the page definition of the page, add an invokeAction Executable and bind it to the method needed to be executed. 3. Using combination of Server and Client Listeners : If the page does not have any page definition, then to call a method in backing bean, this approach can be taken. In this, a serverListener would be added at the document level, which would be calling the method in backing bean. Along with this, a clientListener would be added with "load" type (i.e will be triggered when the page loads), which would queue a serverEvent to trigger the method. 4. Using Page Phase Listener :This should be the last resort. Care should be taken when using this approach since the Phase Listener would be called for each request sent by the client.Zeeshan Baig's blog covers this scenario.

    Read the article

  • An Epic Question "How to call a method when the page loads"

    - by Arunkumar Ramamoorthy
    Quite often, there comes a question in OTN, with different subjects, all meaning "How to call a method when my ADF page loads?". More often, people tend to take the approach of ADF Phase Listener by overriding before/afterPhase methods.In this blog, we will go through different options in achieving it.1. Method Call Activity as default activity in Taskflow :If the application is built with taskflows, then this is the best suited approach to take. 1.a. Calling a Data Control Method :To call a Data Control method (ex: A method in AMImpl exposed as client interface), simply Drag and Drop the method as Default Method Call Activity, then draw a control flow case from the method to your page. Once after this, drop the taskflow as region in main page. When we run the main page, the Method Call Activity would be called first, and then the page will be rendered.1.b. Calling a Method in Backing Bean: To call a method in the backing bean before pageload, we can follow the similar approach as above. Instead of binding the Method Call Activity to an action/method binding in pagedef, we bind to the method. Insert a Method Call Activity (and make it as default) from the Component Palette. Double click on to select a method to bind. This approach can also be used, to perform some action in backing bean along with calling a method Data Control (just need to add bindings code in backing bean to execute DC method). 2. Using invokeAction Executable :If the application is built with pages and no taskflows are involved, then this option can be taken into consideration.In the page definition of the page, add an invokeAction Executable and bind it to the method needed to be executed. 3. Using combination of Server and Client Listeners : If the page does not have any page definition, then to call a method in backing bean, this approach can be taken. In this, a serverListener would be added at the document level, which would be calling the method in backing bean. Along with this, a clientListener would be added with "load" type (i.e will be triggered when the page loads), which would queue a serverEvent to trigger the method. 4. Using Page Phase Listener :This should be the last resort. Care should be taken when using this approach since the Phase Listener would be called for each request sent by the client.Zeeshan Baig's blog covers this scenario.

    Read the article

  • Hot Sessions for Oracle World 2012 - Cloud and Mobile Keynote

    - by Grant Ronald
    For those attending Oracle World 2012 Chris Tonas, VP of Application Development Tools, will be talking about Cloud and Mobile on Monday 1st Oct at 10:45am.  Having had a sneak preview of this session already is amazing to see how our development tools, specifically JDeveloper and Oracle ADF, are embracing mobile and cloud development.  If you want to know more, you'll have to come along to this session!

    Read the article

  • Tutorial on Hudson, JUnit and Ant

    - by Grant Ronald
    Often when discussing ADF we often show the features for developing applications. However, writing applications is only one part.  Building in a team, integrating code, testing it...these are equally important to the success of the project.  If you would like to find out how features in JDeveloper can help you build, maintain, integrate and test your application then check out this tutorial.

    Read the article

  • ????showPopupBehavior??region??popup??

    - by Todd Bao
    ???????ADF??????????????:?????????showPopupBehavior???jsp?,???????popup????jsp??region(??Bounded Taskflow)????jsff?????????showPopupBehavior?poupId???????????????<af:region value="#{bindings.inner1.regionModel}" id="r1"/><af:commandButton text="Pop UP" id="cb1">  <af:showPopupBehavior popupId="r1:p1"/></af:commandButton>?????popupId - r1:p1 - ?????id?r1?region????id?p1?popup???jsff?id??????????????,expression builder???????,design time checker????popupId????,?????????????????? Todd

    Read the article

  • Sorting tasks to assign

    - by Diego
    I've got a problem that I don't know where to start. I'd realy appreciate some help. The problem: I have several T task that must be done in D days by just 1 employee (let's forget using several resources right now). Each task can be done in some times (not all tasks can be done all time). e.g.: If my employee starts working at 8 o'clock and one task is "call a client". Maybe the client office opens at 9 o'clock. Also each task has a duration (really estimated). It is supposed that the D days are enough to do all task. I've to sort the tasks to the employee. e.g.: at monday 8:00 do task 7, then at 9:30 starts with task 2. In the example task 7 duration would be 1 and a half hour. Thanks for the help! Diego PD: If someone has a way to make this and it is not an algorithm never minds, please answer and I'll manage to think the algorithm. I just don't know how to face the problem. Edit Would Project be usefull? Edit 2 Tasks / Jobs dependency is NOT required

    Read the article

< Previous Page | 27 28 29 30 31 32 33 34 35 36 37 38  | Next Page >