While trying to understand how Navision 5 can communicate with an external application through COM interop, i found the following example:
http://msdn.microsoft.com/en-us/library/aa973247.aspx
The second case implemented is exactly what I want to do. I tested the code (with minor modifications - added some attributes [ComVisible(true)] on the events interface and class) and with these modifications it worked as stated in the example.
However, I cannot understand why we do not get an exception on invoking the COMTimer.Elapsed through the following.
protected virtual void OnElapsed(EventArgs e)
{
Elapsed();
}
Who is hooked to this event? The only "hook" i can see is the mTimer.Elapsed += new ElapsedEventHandler(mTimer_Elapsed); that refers to the Elapsed event of the mTimer.
Normally, Elapsed would be null in the OnElapsed function.
I would appreciate your help. Thanks in advance.
Interesting problem.
WithEvents property on automation creates the handler and attaches it to Elapsed delegate, so this one is not NULL - hence no exception
However, when WithEvents is No, and Timer.Start() is invoked, as you rightly say no exception bubbles up, even though (in theory) Elapsed delegate is null.
The simple explanation to this would be, that NAV attaches empty delegate regardless of WithEvents property. To support that, if you put code in Timer::Elapsed() trigger, then take off WithEvents, and bring it back - the code will still be there (i.e. trigger still exists in unchanged form), which makes me lean towards conclusion that it exists always (i.e. empty delegate).
But of course it's NAV so it couldn't be that simple.
I created a test codeunit from above MSDN example, but made a small change to the automation:
/// <summary>
/// Whenever the internal timer elapses, an event must be fired
/// </summary>
private void mTimer_Elapsed(object sender, ElapsedEventArgs e)
{
OnElapsed(EventArgs.Empty);
throw null;
}
This, in theory, should throw NULL whenever mTimer_Elapsed is invoked - nothing however bubbles up in NAV. I went a bit further and changed this:
///<summary>
/// Invoke the Changed event; called whenever the internal timer elapses
/// </summary>
protected virtual void OnElapsed(EventArgs e)
{
throw new InvalidCastException("test");
//Elapsed();
}
Again, nothing happens in NAV.
Note, that both changes behave as expected if the COM Timer is consumed from within .NET project. This makes me think, that NAV Interop must be capturing exceptions from the automation and handle them internally.
I would however pop that question in Mibuso - someone there will probably know better.
Related
Does anyone know how to write a custom Event Dispatcher based on the javafx.event package? I searched in Google & Co. but didn't find a nice example.
Have anyone a minimalistic example for me? That would be nice - I tried it a few times to understand it, but I failed.
The first thing to realize is how JavaFX dispatches events.
When an Event is fired it has an associated EventTarget. If the target was in the scene-graph then the path of the Event starts at the Window and goes down the scene-graph until the EventTarget is reached. The Event then goes back up the scene-graph until it reaches the Window again. This is known as the "capturing phase" and the "bubbling phase", respectively. Event filters are invoked during the capturing phase and event handlers are invoked during the bubbling phase. The EventHandlers set using the onXXX properties (e.g. onMouseClicked) are special types of handlers (i.e. not filters).
The EventDispatcher interface has the following method:
public Event dispatchEvent(Event event, EventDispatChain tail) { ... }
Here, the event is the Event being dispatched and the tail is the EventDispatchChain built, possibly recursively, by EventTarget.buildEventDispatchChain(EventDispatchChain). This will return null if the event is consumed during execution of the method.
The EventDispatchChain is a stack of EventDispatchers. Every time you call tail.dispatchEvent(event) you are essentially popping an EventDispatcher off the top and invoking it.
#Override
public Event dispatchEvent(Event event, EventDispatchChain tail) {
// First, dispatch event for the capturing phase
event = dispatchCapturingEvent(event);
if (event.isConsumed()) {
// One of the EventHandlers invoked in dispatchCapturingEvent
// consumed the event. Return null to indicate processing is complete
return null;
}
// Forward the event to the next EventDispatcher in the chain
// (i.e. on the stack). This will start the "capturing" on the
// next EventDispatcher. Returns null if event was consumed down
// the chain
event = tail.dispatchEvent(event);
// once we've reached this point the capturing phase has completed
if (event != null) {
// Not consumed from down the chain so we now handle the
// bubbling phase of the process
event = dispatchBubblingEvent(event);
if (event.isConsumed()) {
// One of the EventHandlers invoked in dispatchBubblingEvent
// consumed the event. Return null to indicate processing is complete
return null;
}
}
// return the event, or null if tail.dispatchEvent returned null
return event;
}
You're probably wondering where dispatchCapturingEvent and dispatchBubblingEvent are defined. These methods would be created by you and would invoke the appropriate EventHandlers. You might also be wondering why these methods return an Event. The reason is simple: During the processing of the Event these methods, along with tail.dispatchEvent, might alter the Event. Other than consume(), however, Event and its subclasses are basically immutable. This means any other alterations require the creation of a new Event. It is this new Event that should be used by the rest of the event-handling process.
The call to tail.dispatchEvent will virtually always return a new instance of the Event. This is due to the fact each EventDispatcher in the EventDispatchChain is normally associated with its own source (e.g. a Label or Window). When an EventHandler is being invoked the source of the Event must be the same Object that the EventHandler was registered to; if an EventHandler was registered with a Window then event.getSource() must return that Window during said EventHandler's execution. The way this is achieved is by using the Event.copyFor(Object,EventTarget) method.
Event oldEvent = ...;
Event newEvent = oldEvent.copyFor(newSource, oldEvent.getTarget());
As you can see, the EventTarget normally remains the same throughout. Also, subclasses may override copyFor while others, such as MouseEvent, may also define an overload.
How are the events actually dispatched to the EventHandlers though? Well, the internal implementation of EventDispatcher makes them a sort of "collection" of EventHandlers. Each EventDispatcher tracks all filters, handlers, and property-handlers (onXXX) that have been added to or removed from its associated source (e.g. Node). Your EventDispatcher doesn't have to do this but it will need a way to access wherever you do store the EventHandlers.
During the capturing phase the EventDispatcher invokes all the appropriate EventHandlers added via addEventFilter(EventType,EventHandler). Then, during the bubbling phase, the EventDispatcher invokes all the appropriate EventHandlers added via addEventHandler(EventType,EventHandler) or setOnXXX (e.g. setOnMouseClicked).
What do I mean by appropriate?
Every fired Event has an associated EventType. Said EventType may have a super EventType. For instance, the "inheritance" tree of MouseEvent.MOUSE_ENTERED is:
Event.ANY
InputEvent.ANY
MouseEvent.ANY
MouseEvent.MOUSE_ENTERED_TARGET
MouseEvent.MOUSE_ENTERED
When dispatching an Event you have to invoke all the EventHandlers registered for the Event's EventType and all the EventType's supertypes. Also, note that consuming an Event does not stop processing of that Event for the current phase of the current EventDispatcher but instead finishes invoking all appropriate EventHandlers. Once that phase for that EventDispatcher has completed, however, the processing of the Event stops.
Whatever mechanism you use to store the EventHandlers must be capable of concurrent modification by the same thread. This is because an EventHandler may add or remove another EventHandler to or from the same source for the same EventType for the same phase. If you stored them in a regular List this means the List may be modified while you're iterating it. A readily available example of an EventHandler that may remove itself is WeakEventHandler. A WeakEventHandler will attempt to remove itself if it is invoked after it has been "garbage collected".
Also, I don't know if this is required, but the internal implementation doesn't allow the same EventHandler to be registered more than once for the same source, EventType, and phase. Remember, though, that the EventHandlers added via addEventHandler and those added via setOnXXX are handled separately even though they are both invoked during the same phase (bubbling). Also, calling setOnXXX replaces any previous EventHandler set for the same property.
I've added Coded UI Tests to my ASP.NET MVC solution in Visual Studio 2013. I was dismayed to see how slowly the tests run; each page just sits there for up to a minute or more before the test machinery wakes up and starts filling in the form fields.
After some experimentation (including turning off SmartMatch), I've discovered that simply calling
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;
solves the problem. But, as expected, the test frequently fails because the UI thread isn't ready for the test machinery to interact with the controls on the form.
Calling
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.UIThreadOnly;
makes the test run reliably, if slowly.
Any thoughts or suggestions? Any hope that someone might have some insight into the magic baked into the WaitForReady machinery? Are there any other settings related to WaitForReady that I can fiddle with besides WaitForReadyLevel?
After a bit of experimentation, I've worked out what appears to be a combination of settings that allows my Coded UI Tests to reliably run at full speed -- faster than I could interact with the website by hand.
Note: The relevant "documentation" (if you call a blog "documentation") can be found here:
Playback configuration settings
Retrying failed playback actions.
The trick requires several modifications to the default playback settings:
Setting WaitForReadyLevel = WaitForReadyLevel.Disabled allows the test to run at full speed. But it also disables the (slow!) magic that waits until it's safe to interact with controls on the page.
Setting a MaximumRetryCount and attaching an error handler deals with most of the errors that result from disabling the "wait for ready" magic. Because I've baked a 1 second Sleep into the retry logic, this value is effectively the number of seconds I'm willing to wait for the page to load and become responsive.
Apparently, failure to find the control under test is not one of the errors handled by the error handler/retry mechanism. If the new page takes more than a few seconds to load, and the test is looking for a control that doesn't exist until the new page loads, the test fails to find the control and the test fails. Setting ShouldSearchFailFast = false solves that problem by giving you the full timeout time for your page to load.
Setting DelayBetweenActions = 500 appears to work around a problem that I see occasionally where the UI misses a button click that occurs immediately after a page has loaded. The test machinery seems to think that the button was clicked, but the web page doesn't respond to it.
The "documentation" says that the default search timeout is 3 minutes, but it's actually something greater than 10 minutes, so I explicitly set SearchTimeout to 1 second (1000 ms).
To keep all of the code in one place, I've created a class that contains code used by all of the tests. MyCodedUITests.StartTest() is called by the [TestInitialize] method in each of my test classes.
This code really should be executed only once for all of the tests (rather than once per test), but I couldn't figure out a way to get the Playback.PlaybackSettings calls to work in the [AssemblyInitialization] or [ClassInitialization] routines.
/// <summary> A class containing Coded UI Tests. </summary>
[CodedUITest]
public class UI_Tests
{
/// <summary> Common initialization for all of the tests in this class. </summary>
[TestInitialize]
public void TestInit()
{
// Call a common routine to set up the test
MyCodedUITests.StartTest();
}
/// <summary> Some test. </summary>
[TestMethod]
public void SomeTest()
{
this.UIMap.Assert_HomePageElements();
this.UIMap.Recorded_DoSomething();
this.UIMap.Assert_FinalPageElements();
}
}
/// <summary> Coded UI Test support routines. </summary>
class MyCodedUITests
{
/// <summary> Test startup. </summary>
public static void StartTest()
{
// Configure the playback engine
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;
Playback.PlaybackSettings.MaximumRetryCount = 10;
Playback.PlaybackSettings.ShouldSearchFailFast = false;
Playback.PlaybackSettings.DelayBetweenActions = 500;
Playback.PlaybackSettings.SearchTimeout = 1000;
// Add the error handler
Playback.PlaybackError -= Playback_PlaybackError; // Remove the handler if it's already added
Playback.PlaybackError += Playback_PlaybackError; // Ta dah...
}
/// <summary> PlaybackError event handler. </summary>
private static void Playback_PlaybackError(object sender, PlaybackErrorEventArgs e)
{
// Wait a second
System.Threading.Thread.Sleep(1000);
// Retry the failed test operation
e.Result = PlaybackErrorOptions.Retry;
}
}
Coded UI searches for controls on the screen and that search is quite fast if successful. However if the search fails then Coded UI has another try using a "smart match" method and that can be slow. The basic way of avoiding Coded UI falling back to using smart matching is to remove or simplify search items that may change from run to run.
This Microsoft blog gives lots of explanation of what happens and how to fix it. The example therein shows a speedup from 30 seconds to 8 seconds by changing a search string from
Name EqualsTo “Sales order (1 - ceu) - Sales order: SO-101375, Forest Wholesales”
to
Name Contains “Sales order (1 - ceu) - Sales order: SO”
Seems like it is captured from microsoft dynamics tool. Please check the length of the string captured from inspect tool. You will be finding some hidden character. just order (1 - ceu). Else just move the cursor from "(" to ")". You will be finding cursor is not moving sometime when pressing right arrow key.
I have a custom workflow done in Visual Studio 2010 (for SharePoint 2010 site). I have a task assigned to a group. All users receive task assignment notification emails without any problem. By default any of them approving it shows the task as completed.
My task will be considered approved only when ALL members of the group approve that. How to achieve this please?
Any help will be appreciated.
Thanks
Every time I've seen multi-approval workflows, it has always included multiple tasks. I don't think a single task can be some percentage approved. It's either pending or approved (or denied, etc).
I can think of two possibilities:
In your custom workflow, at the time that the task is being assigned, rather than assigning a single task to the group, assign one task to each member of the group.
Add an ItemUpdating event receiver to the Task list item that maintains (another list, database, etc?) a list of users have approved the task. Once all users in the group have approved the task, allow the update to go through, otherwise leave the status as pending.
Try keeping track of the number of individual tasks assigned and individual tasks completed. When completed==assigned, check to make sure all tasks resulted in approval and take the required action from there.
Technically you could create a custom task type that uses a different field, and store all of the user names in it, and check them off one by one with a custom task form... but it's actually a lot simpler if you create multiple tasks in parallel.
Here is an example of how to do it, http://msdn.microsoft.com/en-us/library/hh128696.aspx (Watch the video too!) BUT-- there is one part of his example that's a bad practice: he initializes the InitialChildData IList inside the Initialzed event of the Replicator activity... that's why he has to initialize the first child in there, and the rest in the ChildInitialized event... the correct way is to have a code activity run immediately before you get to the replicator and set up your IList. Then you can just leave all of the actual initialization code in the childInitialized handler. In my real life working version I have no replicator initialized handler at all.
I'm about to go into an example that goes along with the Scot Hilier one linked above, like an errata addendum type thing, so don't get upset when you realize this code isn't the entire solution.
For example, if my multi approver list is using a comma delimited string property of my workflow called Assignees (maybe I get it from the intialization data of the workflow, maybe a previous task form... that's your own business)
private void prepareCodeActivity_Invoked(object sender, EventArgs e) {
Assignees = DesignatedApprovers.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
Assignees is a List<string> in this case, and I have bound the InitialChildData property of the replicator to it
private void replicateTasks_ChildInitialized(object sender, ReplicatorChildEventArgs e) {
// do all of your task setup here (e.InstanceData is the single string for this child)
// note I'm setting properties of my custom activity, not the task itself
// each child instance of the replicator gets it's own instance of it.
generalApprovalTask.TaskAssignedTo = e.InstanceData.ToString();
generalApprovalTask.TaskTitle = string.Format(MyStrings.GeneralApprovalTaskTitle,
workflowProperties.Item.File.Name)
// log something!
}
Just a small oversight by Mr Hillier, but it's generally a good example, so we'll forgive him.
If you want to examine the results, do it in the ChildCompleted handler of the replicator. (Mr Hilier does not cover this part either.)
public int FailedApprovals { get; set; }
/// <summary>
/// This is called upon the completion of the child tasks. Here is where we check the outcome.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void replicateTasks_ChildCompleted(object sender, ReplicatorChildEventArgs e) {
if (e.Activity is MyGeneralApprovalTaskActivity) {
var act = e.Activity as MyGeneralApprovalTaskActivity;
if (act.TheTaskOutcome != MyStrings.ApprovedString) {
FailedApprovals++;
}
// log something!
}
}
It was suggested that a Replicator Activity with Until condition is the proper way to go for this. As per my research this sounds like a good solution.
http://wiki.windowsworkflowfoundation.eu/default.aspx/WF/UntilConditionAndTheReplicatorActivity.html
I welcome any further suggestions/approaches.
I just finished my first own example with activities/places and MVP. all works fine but some events aren't send or received properly if i change back to a place (from another place). but on "moduleLoad" where this place is set as default place all works fine. i think it shouldn't make a difference if a place/activity is started on moduleLoad (via historyHandler = new PlaceHistoryHandler(historyMapper); historyHandler.register(placeController, eB, defaultPlace); historyHandler.handleCurrentHistory();) or via placeController.goTo(place); , should it?
via debugging i checked the order of event registration, event sending and event receiving (all is executed in start(...) of the activity). the problem is that all receiver don't receive the event if start() is executed via goTo(place) (registration and sending works fine). But if an event is sent after start() or within start()-executed on moduleLoad all works fine!
my activity start looks like that:
#Override
public final void start(final AcceptsOneWidget panel, final EventBus eventBus) {
// register events - to manipulate visibility of some display areas
eventBus.addHandler(SelectedEvent.TYPE, this);
//initiate presenters -(pseudo code)
[presenter that receives SelectedEvent]
[presenter that sends SelectedEvent]
//ading presenter's asWidgets to screen -> panel.setWidget..
...
}
#Override
public final void onSelected(final SelectedEvent event) {
//do something
}
(the use case for sending this event on start is, that i want say nothing is selected - the event's payload is null)
the problem is that neither the presenter's nor the activity's onSelected -method is called if the start() is called via goTo. But in all cases (checked with debugger) the registering on event occurs before sending it. what should i do?
Javascript is not multithread.
When you call a goTo() method, your activities will be started one after the others. If you fire an event inside a start(), the event will be dispatched before the remaining activities are started. So there is a good chance that the activity handling that event has not been started yet (the registration was not done).
You can solve your problem with the following code:
Scheduler.get().scheduleDeferred(new ScheduledCommand()
{
#Override
public void execute()
{
//Fire the event
}
});
Scheduler is a utility class provided by GWT. ScheduleDeferred will execute the command after the current browser event loop returns.
So, by pasting this code in a start() , you know the event will be fired as soon as every activity is started.
In a previous SO question it was recommended to me to use callback/event firing instead of polling. Can someone explain this in a little more detail, perhaps with references to online tutorials that show how this can be done for Java based web apps.
Thanks.
The definition of a callback from Wikipedia is:
In computer programming, a callback is
executable code that is passed as an
argument to other code. It allows a
lower-level software layer to call a
subroutine (or function) defined in a
higher-level layer.
In it's very basic form a callback could be used like this (pseudocode):
void function Foo()
{
MessageBox.Show("Operation Complete");
}
void function Bar(Method myCallback)
{
//Perform some operation
//When completed execute the callback method
myCallBack().Invoke();
}
static int Main()
{
Bar(Foo); //Pops a message box when Bar is completed
}
Modern languages like Java and c# have a standardized way of doing this and they call it events. An event is simply a special type of property added to a class that contains a list of Delegates / Method Pointers / Callbacks (all three of these things are the same thing. When the event gets "fired" it simply iterates through it's list of callbacks and executes them. These are also referred to as listeners.
Here's an example
public class Button
{
public event Clicked;
void override OnMouseUp()
{
//User has clicked on the button. Let's notify anyone listening to this event.
Clicked(); //Iterates through all the callbacks in it's list and calls Invoke();
}
}
public class MyForm
{
private _Button;
public Constructor()
{
_Button = new Button();
//Different languages provide different ways of registering listeners to events.
// _Button.Clicked += Button_Clicked_Handler;
// _Button.Clicked.AddListener(Button_Clicked_Handler);
}
public void Button_Clicked_Handler()
{
MessageBox.Show("Button Was Clicked");
}
}
In this example the Button class has an event called Clicked. It allows anyone who wants to be notified when is clicked to register a callback method. In this case the "Button_Clicked_Handler" method would be executed by Clicked event.
Eventing/Callback architecture is very handy whenever you need to be notified that something has occurred elsewhere in the program and you have no direct knowledge of when or how this happens.
This greatly simplifies notification. Polling makes it much more difficult because you are responsible for checking every so often whether or not an operation has completed. A simple polling mechanism would be like this:
static void CheckIfDone()
{
while(!Button.IsClicked)
{
//Sleep
}
//Button has been clicked.
}
The problem is that this particular situation would block your existing thread and have to continue checking until Button.IsClicked is true. The nice thing about eventing architecture is that it is asynchronous and let's the Acting Item (button) notify the listener when it is completed instead of the listener having to keep checking,
The difference between polling and callback/event is simple:
Polling: You are asking, continuously or every fixed amount of time, if some condition is meet, for example, if some keyboard key have been pressed.
Callback: You say to some driver, other code or whatever: When something happens (the keyboard have been pressed in our example), call this function, and you pass it what function you want to be called when the event happens. This way, you can "forget" about that event, knowing that it will be handled correctly when it happens.
Callback is when you pass a function/object to be called/notified when something it cares about happens. This is used a lot in UI - A function is passed to a button that is called whenever the button is pressed, for example.
There are two players involved in this scenario. First you have the "observed" which from time to time does things in which other players are interested. These other players are called "observers". The "observed" could be a timer, the "observers" could be tasks, interested in alarm events.
This "pattern" is described in the book "Design Patterns, Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson and Vlissides.
Two examples:
The SAX parser to parse XML walks
trough an XML file and raises events
each time an element is encountered.
A listener can listen to these
elements and do something with it.
Swing and AWT are based on this
pattern. When the user moves the
mouse, clicks or types something on
the keyboard, these actions are
converted into events. The UI
components listen to these
events and react to them.
Being notified via an event is almost always preferable to polling, especially if hardware is involved and that event originates from a driver issuing a CPU interrupt. In that case, you're not using ANY cpu at all while you wait for some piece of hardware to complete a task.