Multiple End events in one Process - bpmn

Can I use multiple End event in One Process?
if yes, How to declare which End Event is Main End Event?
To Clarify the Question, let me demonstrate it.
We have main process that has a sub process. There is a inclusive or parallel gateway inside sub process that branch out into multiple paths. All of the paths leads to None End event.
Which End event is triggered in order to continue main process?
for example in attached image Example , I want Main Process to be continued and run Task1, whenever End Event B be triggered (None of the both other End events, A or C)

I would add an exlusive gateway after your subprocess that is asking the question "What was the result of the subprocess?". But I think you could also simplify the model:
Since the activities related to A and C are always executed but have no significance for the rest of the process, I would do them separattely from B and then check if B was the case or not. This basically translates to "We have to do A and C but we really only care about B".
Here are both versions as I would have done them.

Related

Do all end events end the whole process?

In the following example, if arriving at "dealer reminded", will this end the whole process? Since the branch is triggered by a non-interrupting event, we could also arrive at "order confirmed".
I hope it works the way that both end events must be reached (assuming "answer a bit late" has been triggered), but in case of the interrupting event "answer overdue" I guess "order not deliverable" will terminate the whole process. Is this correct?
End events only end their respective branch. They "eat" the token, nothing else.
There is a different element that deletes all tokens of its scope, therefore effectively ending it: the "terminate" end event.
So no, "order not deliverable" will not terminate the process and a token at "remind dealer" will remain there.
The BPMN spec says (on p. 246) that "All the tokens that were generated within the Process MUST be consumed by an End Event before the Process has been completed". This means that the process ends when all parallel paths have completed, implying that both a "Dealer reminded" and an "Order confirmed" (or, alternatively, an "Order not available") end event must occur for completing a process according to your model.

How to limit the number of processes being spawned at a time?

I am working on a VB.NET Windows Forms application where the user is supposed to be able to determine how many processes the application is allowed to launch at a time.
My current method mostly works but I've noticed that occasionally the application goes over the set amount. I use two global variables for this, _ConcurrentRuns which is 0 at the start of the application, and _MaxConcurrentRuns which is set by the user.
Private _sync As new Object()
' This is called Synchronously
Private Function RunModel() As Boolean
If CancelExectuion Then Return CancelCleanup()
Do While True
SyncLock _sync
If _ConcurrentRuns < _MaxConcurrentRuns Then
Interlocked.Increment(_ConcurrentRuns)
Exit Do
End If
End SyncLock
Threading.Thread.Sleep(50)
Loop
'This is what will launch an individual process and close it when finished
ret = RunApplication(arg)
' The process has been closed so we decrement the concurrent runs
Interlocked.Decrement(_ConcurrentRuns)
Return ret
End Function
The goal is to let only one thread exit the while loop at a time, I'm not able to catch it in the debug mode however in the task manager it will occasionally go 1-3 processes over what it's supposed to use. This makes me assume that somehow multiple threads are getting inside the synclock somehow, but I have no clue how that could be happening.
I will be very grateful for any and all help that can be provided, thanks for taking the time to read my question.
So it appears that my solution works for this, I don't want to delete this question because it might be helpful to somebody else in the future.
Answer: Use better process monitoring software / set priority to high in task manager.

Updating UI while waiting for tasks to finish

I have a vb.net application processing a large amount of data. Due to the memory requirements of the process I am doing this batch-wise, with an overall planned structure as follows:
Do while Start < TotalNumberOfObjects
[cache data used for the upcoming batch]
For i = Start to Stop
[process data using multiple tasks...for example:]
t=taskfactory.startnew(doStuff(i))
TaskList.TryAdd(t.ContinueWith(Sub()
Me.BeginInvoke(DelegateUpdateProgress, {progress})
End Sub))
Next
[Wait for tasks to complete...
Normally I would wait for the tasks using task.waitall(),
but this will cause the UI to wait to update until all tasks are complete]
Start = Stop+1
Stop = Stop+Increment
[clear data from batch that was just completed]
loop
What's the proper way to:
Wait for all the tasks to complete before moving to the next batch?
Update the UI with the overall progress as each task completes?
My target framework is .NET 4.0.
I appreciate any input.
EDIT: Currently I am updating the UI upon completion of each task using task.continuewith() and calling me.beginInvoke to update the form,
TaskList.TryAdd(t.ContinueWith(Sub()
Me.BeginInvoke(DelegateUpdateProgress, {progress})
End Sub))
However, this is incompatible with how I would expect to wait for a list of tasks to complete, task.waitall(tasklist) because calling task.waitall will cause the UI thread to wait to update until all the tasks are complete.
First you need to set up a delegate and then use Dispatcher.Invoke
In the example below, a button is changed from enabled to disable (or the other way around):
Delegate Sub SetRecordButtonEnabledCallback(ByVal Enabled As Boolean)
Friend Sub SetRecordButtonEnabled(ByVal Enabled As Boolean)
Me.btnDGRecord.IsEnabled = Enabled
End Sub
after that all you need to do is call the following code from within your timer to invoke it:
Dim DesiredValue as Boolean = True
Me.Dispatcher.Invoke(New SetRecordButtonEnabledCallback(AddressOf SetRecordButtonEnabled), New
Object() {DesiredValue})
Why don´t you put your routine in a Backgroundworker structure?
So, while you code process data, you´re ready to update any UI component you have.
If necessary, you may also update UI from Backgroundworker, but you need to have some special requirements to do this.
You may consult here:
https://msdn.microsoft.com/en-us//library/ywkkz4s1.aspx

Multithreading Webbrowsers

I am currently making a vb program that i plan to make very big. I have a decent knowledge of visual basic but today i came across something i do not understand. Because of the huge size of my program , i decided to try and keep the program as organized as possible by putting specific subs in modules. These subs consist of httprequest , webbrowsers(control), webclients and alot of loops. In order to prevent these subs from lagging my main application i thread them using threading.thread and i start them from my main form. But this leads to two problems.
Problem 1: The threads cannot in any way interact with the main form.
Once the a httprequest or webclient collects the information from my desired website, i am trying to make it add the info to a listbox in my main form, So what i did is it typed
Msgbox("Info Sent")
form1.listbox1.items.add(String)
The first messagebox will show but although the code right under it runs, nothing is added to the first forms listbox.I am not using delegates to transfer the information, instead, although its not a good habit, i am using checkforillegalcrossovers.
Problem 2: Threading with a webbrowser.
Threading with a webbrowser using threading.thread also does not work because it causes an active x error. After looking it up i found that a solution was to use a single threaded apartment but this would not work because i may need multiple threads running off the same sub at once.
One solution that i have found to this problem is creating another form completely and setting it invisible, and since the form is its own thread i do not need to use threading.thread , but the problem comes when i am trying to create multiple threads, or else i can somehow dynamically create the threads and put the subs inside of it programically this method wont work And even if it does i feel that it is sloppy so i will leave this for one of two last resorts.
The other solution is the most simple one in which i just put all of the code in the main form, but if i keep on doing that form1 is gonna become huge and sloppy, doing this wont solve the webbrowser problem either and even when using regions i still feel that something that 1000+ lines deserves its own class.
There must be some solution out there that solves these problems. Any help would be appreciated, Thanks.
I checked my code for updating the progress bar, and using a single thread with synclock will NOT work. They way I make it work is perform the step of the pbar each time after a thread is started as I have limited total threads (say less than 5 threads). Thus, even the progress bar steps before the threads are finished, but it will not progress further before new threads started. It is not 100% accurate but it more or less telling the progress
'update the progress bar
some_form.PBar1.PerformStep()
' This while loop is to count the existing running thread,
' and determine whether new thread should start
While 1
Dim t2 = New System.Threading.Thread(Sub() WaitForPermission())
t2.Start()
t2.Join()
If proceed_gen Then
Exit While
End If
End While
'Start doing what I need to do
Dim t1 = SomeSub()
t1.Start()
'End of code, as VB doest not have thread.detach()
Correct me if I am wrong, but you probably have to use a background worker. I know this is annoying, but this is the limitation of VB.net.
Or, you can have something like this (pseudo code, not tested)
structure some_struct
'define the strings you want to update, and their status such that
'main() knows if you need to update the stuff to the form
' You can also put how many threads are running, and the status of each thread,
'such that the main knows if all threads are completed
end structure
sub your_sub()
'Manipulate the website, and update the data structure with
'proper stuff you need
end sub
sub main(){
dim t1 = New System.Threading.Thread(Sub() your_sub())
t1.start()
' I am listing only one threads here, but start as many as you want
'check if there are strings that you need to update to the form
while 1
'check if there are any stuff you want to update from the data structure.
' Make sure you use synclock on the data structure, so each thread won't fight each other on accessing the data struct
dim should_update as boolean = false
should_update = 'Something thatyou should implement to judge whether you should update the form.
'You can start a thread and join it so the thread won't fight with other threads for accessing the data structure
dim some_string as string
if should_update
some_string = 'You may also need a thread to join to get the stuff you need. Dim the string as an array if it is required.
'You can also try pass by ref
'if you need to use thread to access the data structure to know if you need to update the form
form1.listbox1.items.add(some_string )
end if
end while
end sub
This is an ugly solution, but it will help you do the job...

Turning For loop in Backgroundworker into multithreader

I have a background worker where I currently am running a setup to loop through and send the http commands to these devices to update their firmware. Currently it's very slow, looping though each one and sending it.
My first question is, how can I multithread this so increase the speed? Usually I would make a task per device, add to a task array, and do a "wait all". But the device numbers could get up to 300 here so I want to limit it to a smart amount and do it dynamically.
And my second question is, is it wise to do so in the back groundworker that is already a thread (so I can show the progress bar)? Or is there another way to do it that is smarter?
Here's the current setup:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork
'loop through devices
For Each assignment As FirmwareAssign In assignList
'firmwareassign is a struct with credentials for http, ip address, and device brand as strings
'Send Update Request
Select Case assignment.devcebrand.tolower
Case "brand1"
Logstatement += brand1.updateFirmware(assignment, assignment.deviceipaddress)
Case "brand2"
Logstatement += brand2.updateFirmware(assignment, assignment.deviceipaddress)
Case "brand3"
Logstatement += brand3.updateFirmware(assignment, assignment.deviceipaddress)
End Select
'don't worry, not real names of my classes
Next
End Sub
These functions are network based. They will grab the new firmware image, and send it to the ip address over the network. So I also want to limit it since we don't want the bandwidth to go nuts. Then it will add it to the logstatement (a string) to display at the end for the user to know if something went wrong.
Since you are sending these across the network and your bottle-neck is likely the network, running multiple threads will not speed it up, if anything it will slow down.
If this is not the case, or you want to test this anyway, here are your 2 answers:
1: If you are already doing a collection, in this case a task array, your are almost there. What I do is stick another loop in your current loop and run while the array/collection length is greater that X (maybe 10 in your case) and in that loop, check the thread status and remove any of those that are complete. This will make it jump out of the inner loop and add more threads until you hit X again.
2: While I don't think there is anything that prevents you from running threads from other threads, the logistics of getting updates back to the GUI might be a nightmare. I would spawn the threads from your main thread which makes progress updates real easy.