Skip to Content
0

how do I develop a multithreading application within PowerBuilder classic?

Jan 17, 2017 at 09:34 AM

430

avatar image
k k

hi guys

there was a legacy program need to maintain,then I tried to check a batch number of product that if supplies was less than all sells,I believe it's a good experience for

colleagues that after scaned the barcode of that batch number application then checked the supplies and sells aysnchrously.althought I have searched Google,however Powerbuilder is less infomation I could found about multithreading,it's not a clear instrution in Powerbuilder help as well.

I'm not sure two questions about multithreading within powerbuilder

#1 if the exception is going to occur when SharedObjectRegister the same name when open two windows like following?

code:

window w_1
opensheet(w_1,"w_inv",w_main,0,Original! )

// then in two same w_inv windows exectue SharedObjectRegister with same name in a //same time,is it going to ocurr the exception?

SharedObjectRegister ('nov_checkvalidobject', ls_var)

#2 some pages said that main thread and sub thread are independent,does it mean that if need to execute SQL select syntax,I can't use sqlca transaction which has connected to a database in main thread?

please take a look at my code,please give me suggestion that I have done wrong or should be aware.thanks in advance


//w_inv instance variable:

//long ll_multithreadcount
//string is_sbmodel
//nov_checkvalidobject tarea_No[ ]

//this is wf_multithread_cal

//long as_row

string ls_var
ErrorReturn ler_error
long ll_threadcurrent



ll_threadcurrent=ll_multithreadcount
ls_var = 'objeto_' +string(ll_threadcurrent)


if is_new='0' then
cb_add_main.enabled=false

elseif is_new='1' then
cb_delete_main.enabled=false
cb_delete_sub.enabled=false
end if

ler_error = SharedObjectRegister ('nov_checkvalidobject', ls_var)

choose case ler_error
case SharedObjectExistsError!

messagebox("Error","The instance name is already used",stopsign!)

if is_new='0' then
cb_add_main.enabled=true

elseif is_new='1' then
cb_delete_main.enabled=true
cb_delete_sub.enabled=true
end if


return -1
case SharedObjectCreateInstanceError!

messagebox("Error","The object could not be created",stopsign!)

if is_new='0' then
cb_add_main.enabled=true

elseif is_new='1' then
cb_delete_main.enabled=true
cb_delete_sub.enabled=true
end if


return -1

case SharedObjectCreatePBSessionError!

messagebox("Error","The object in the session could not be created",stopsign!)

if is_new='0' then
cb_add_main.enabled=true

elseif is_new='1' then
cb_delete_main.enabled=true
cb_delete_sub.enabled=true
end if


return -1
end choose


ler_error = SharedObjectGet (ls_var, tarea_No[ll_threadcurrent])
choose case ler_error
case SharedObjectCreateInstanceError!

messagebox("Error","The local reference to the shared object could not be created",stopsign!)

if is_new='0' then
cb_add_main.enabled=true

elseif is_new='1' then
cb_delete_main.enabled=true
cb_delete_sub.enabled=true
end if


return -1
case SharedObjectNotExistsError!

messagebox("Error","The instance name is not registered ",stopsign!)

if is_new='0' then
cb_add_main.enabled=true

elseif is_new='1' then
cb_delete_main.enabled=true
cb_delete_sub.enabled=true
end if


return -1
end choose

tarea_No[ll_threadcurrent].POST of_checkvalid(dw_2,as_row)

SharedobjectUnregister(ls_var)

ll_multithreadcount++

if is_new='0' then
cb_add_main.enabled=true

elseif is_new='1' then
cb_delete_main.enabled=true
cb_delete_sub.enabled=true
end if



return 0

//nov_checkvalidobject: there is a function in nov_checkvalidobjec which is of_checkvalid

// there is 2 parameters in it

//paramter #1 datawindow as_dw

//paramter #2 long as_therow

//of_checkvalid function code:

decimal ld_invnum,ld_depnum
string ls_prodno,ls_batchno,ls_prodadd

if as_therow<0 or as_therow>as_dw.rowcount() then return -1

ls_prodno=as_dw.getitemstring(as_therow,"prod_no")
ls_batchno=as_dw.getitemstring(as_therow,"batch_no")
ls_prodadd=as_dw.getitemstring(as_therow,"prod_add")

if isnull(ls_prodno) or trim(ls_prodno)="" or isnull(ls_batchno) or trim(ls_batchno)="" or isnull(ls_prodadd) or trim(ls_prodadd)="" then return -2
//check the number of all sells
select isnull(sum(inv_num),0) into :ld_invnum from inv_sub where prod_no=:ls_prodno and batch_no=:ls_batchno and prod_add=:ls_prodadd;

//check the number of all suppliers

select isnull(sum(dep_num),0) into :ld_depnum from dep_sub where prod_no=:ls_prodno and batch_no=:ls_batchno and prod_add=:ls_prodadd;

if ld_invnum>ld_depnum then
as_dw.setitem(as_therow,"if_is_valid","failed")
return -3
end if


as_dw.setitem(as_therow,"if_is_valid","pass")
return 0

10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

2 Answers

Best Answer
René Ullrich Jan 17, 2017 at 11:59 AM
0

Hi,

#1: The name must be unique for registered objects in the application. If you try to register a second object with the same name the function SharedObjectRegister should return SharedObjectExistsError!

You may use a shared or global variable instead of instance variable as thread counter.

#2: You can't use the transaction object from main thread (SQLCA) in a shared object. You need a separate database connection for each shared object if you want to access the database.

One parameter of function of_checkvalid of your shared object is a datawindow control. I think the shared object cannot access this object from main thread. You may pass only nonvisualobjects. If you want to check data from a datawindow you may pass it as blob (see function GetFullState / SetFullState).

To return a result from shared object to main thread you need a (nonvisual) callback object with a function you can call from the shared object.

HTH

Share
10 |10000 characters needed characters left characters exceeded
Roland Smith Jan 17, 2017 at 01:49 PM
0

Each background thread has its own set of global variables which includes sqlca. The background thread will have to connect to the database before performing any SQL statements.

When calling SharedObjectRegister, the instancename must be unique. You can create a global variable or shared variable within the window that you increment before each call and use it in the name like this:

gi_instance ++

ls_instance = "instance" + String(gi_instance)

SharedObjectRegister("objectname",ls_instance)

Share
10 |10000 characters needed characters left characters exceeded