Dispatcher Problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Dispatcher Problem

AndyF.
This post was updated on .
Hi Chaps

I have attempted to purloin some of the code shipped with IP in Action and, following issues, I have even gone to the lengths of reading the book!

I am getting the error 'expect Delegate, got Function' when I use the following code. FYI I am passing in a reference to a WPF textBox so I should have a dispatcher on my UI element

I have removed all of the threading pipe reading stuff just to leave 'test' code:

import System
import System.IO
import Avacta.Optim.Server.WebServices
import Avacta.Optim.Server.DataModel
import sys
import clr
import time

from System import Console
from System.Threading import Thread, ThreadStart

def SetDispatcher(ui_element):
global dispatcher # needed else "Exception: 'NoneType' object has no attribute 'BeginInvoke'"
dispatcher = ui_element.Dispatcher

def Dispatch(function, *args):
dispatcher.BeginInvoke(lambda *_: function(*args))

def GetDispatchFunction(function):
return lambda *args: Dispatch(function, *args)

class ListOutput:
def __init__(self, textbox):
self.textbox = textbox

def write(self, string):
Dispatch(self.addText, string) # error: "expect Delegate, got Function"
# self.addText(string) # ok works fine w-w/o dispatcher stuff

def addText(self, string):
textbox.AppendText(string)

if textbox != None:
listout = ListOutput(textbox)
sys.stdout = listout
SetDispatcher(textbox)

print "Define running"
#running = True

Thread.Sleep(0)
time.sleep(2)

print "Start The Comms Thread..."
#comms_t = Thread(ThreadStart(run_comms))
#comms_t.Start()

Thread.Sleep(0)
time.sleep(2)

Any clues would be greatly appreciated!

AndyF.
Reply | Threaded
Open this post in threaded view
|

Re: Dispatcher Problem

Dino Viehland
AndyF wrote:

> Hi Chaps
>
> I have attempted to purloin some of the code shipped with IP in Action and,
> following issues, I have even gone to the lengths of reading the book!
>
> I am getting the error 'expect Delegate, got Function' when I use the
> following code. FYI I am passing in a reference to a WPF textBox so I should
> have a dispatcher on my UI element
>
> I have removed all of the threading pipe reading stuff just to leave 'test'
> code:
>
> import System
> import System.IO
> import Avacta.Optim.Server.WebServices
> import Avacta.Optim.Server.DataModel
> import sys
> import clr
> import time
>
> from System import Console
> from System.Threading import Thread, ThreadStart
>
> def SetDispatcher(ui_element):
> global dispatcher # needed else "Exception: 'NoneType' object has no
> attribute 'BeginInvoke'"
> dispatcher = ui_element.Dispatcher
>
> def Dispatch(function, *args):
> dispatcher.BeginInvoke(lambda *_: function(*args))
>
> def GetDispatchFunction(function):
> return lambda *args: Dispatch(function, *args)
>
> class ListOutput:
> def __init__(self, textbox):
> self.textbox = textbox
>
> def write(self, string):
> Dispatch(self.addText, string) # error: "expect Delegate, got Function"
> # self.addText(string) # ok works fine w-w/o dispatcher stuff
>
> def addText(self, string):
> textbox.AppendText(string)
>
> if textbox != None:
> listout = ListOutput(textbox)
> sys.stdout = listout
> SetDispatcher(textbox)
>
> print "Define running"
> #running = True
>
> Thread.Sleep(0)
> time.sleep(2)
>
> print "Start The Comms Thread..."
> #comms_t = Thread(ThreadStart(run_comms))
> #comms_t.Start()
>
> Thread.Sleep(0)
> time.sleep(2)
>
> Any clues would be greatly appreciated!

The WPF invocation functions just take a type which is typed to "Delegate"
instead of a type of a specific delegate.  Therefore we don't know what type
of delegate to create for you automatically.  Instead you can convert the
Python function into a delegate by calling the delegate type directly, e.g.:

dispatcher.BeginInvoke(System.Action(lambda *_: function(*args)))

or you can use another delegate type (e.g. System.Action[object]) with the
appropriate signature you need.


_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Reply | Threaded
Open this post in threaded view
|

Re: Dispatcher Problem

AndyF.
Thank you Dino

modifying my Python dispatcher to read

dispatcher.BeginInvoke(System.Action(lambda *_: function(*args)))

fixed the problem.  Unfortunately for me, utilising the dispatcher has an unforseen side effect - the 'messages' printed to my console only appear when the python script exits.

If I revert the code to bypass all dispatcher code i.e. use the following

    def write(self, string):
        self.texbox.AppendText(string)

then I see the messages arrive in real time.

I have tested launching my PythonEngine class using a thread with both ApartmentState.STA and MTA but this has no discernible effect.

Can you offer any explanation, maybe workaround?

Thanks

AndyF.


Dino Viehland wrote
AndyF wrote:
> Hi Chaps
>
> I have attempted to purloin some of the code shipped with IP in Action and,
> following issues, I have even gone to the lengths of reading the book!
>
> I am getting the error 'expect Delegate, got Function' when I use the
> following code. FYI I am passing in a reference to a WPF textBox so I should
> have a dispatcher on my UI element
>
> I have removed all of the threading pipe reading stuff just to leave 'test'
> code:
>
> import System
> import System.IO
> import Avacta.Optim.Server.WebServices
> import Avacta.Optim.Server.DataModel
> import sys
> import clr
> import time
>
> from System import Console
> from System.Threading import Thread, ThreadStart
>
> def SetDispatcher(ui_element):
> global dispatcher # needed else "Exception: 'NoneType' object has no
> attribute 'BeginInvoke'"
> dispatcher = ui_element.Dispatcher
>
> def Dispatch(function, *args):
> dispatcher.BeginInvoke(lambda *_: function(*args))
>
> def GetDispatchFunction(function):
> return lambda *args: Dispatch(function, *args)
>
> class ListOutput:
> def __init__(self, textbox):
> self.textbox = textbox
>
> def write(self, string):
> Dispatch(self.addText, string) # error: "expect Delegate, got Function"
> # self.addText(string) # ok works fine w-w/o dispatcher stuff
>
> def addText(self, string):
> textbox.AppendText(string)
>
> if textbox != None:
> listout = ListOutput(textbox)
> sys.stdout = listout
> SetDispatcher(textbox)
>
> print "Define running"
> #running = True
>
> Thread.Sleep(0)
> time.sleep(2)
>
> print "Start The Comms Thread..."
> #comms_t = Thread(ThreadStart(run_comms))
> #comms_t.Start()
>
> Thread.Sleep(0)
> time.sleep(2)
>
> Any clues would be greatly appreciated!

The WPF invocation functions just take a type which is typed to "Delegate"
instead of a type of a specific delegate.  Therefore we don't know what type
of delegate to create for you automatically.  Instead you can convert the
Python function into a delegate by calling the delegate type directly, e.g.:

dispatcher.BeginInvoke(System.Action(lambda *_: function(*args)))

or you can use another delegate type (e.g. System.Action[object]) with the
appropriate signature you need.


_______________________________________________
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Reply | Threaded
Open this post in threaded view
|

Re: Dispatcher Problem

Vernon D. Cole
I have not tested this on a GUI screen, but...
You should be able to assign any class with a .write() method to sys.stdout (and/or sys.stderr) so that normal "print" statements/functions and tracebacks will be sent to that method. I use the trick frequently to get a simple logging facility by assigning a text file -- like:
<code>
import sys
my_log = open('my_log_file.txt','w')
sys.stdout = my_log
print 'Hello, Log.'
sys.stderr = my_log
error = 1 / 0
</code>
Is that the kind of 'messages' you were thinking about?
--
Vernon

On Tue, Jun 7, 2011 at 2:00 AM, AndyF. <[hidden email]> wrote:

Thank you Dino

modifying my Python dispatcher to read

dispatcher.BeginInvoke(System.Action(lambda *_: function(*args)))

fixed the problem.  Unfortunately for me, utilising the dispatcher has an
unforseen side effect - the 'messages' printed to my console only appear
when the python script exits.

If I revert the code to bypass all dispatcher code i.e. use the following

   def write(self, string):
       self.texbox.AppendText(string)

then I see the messages arrive in real time.

I have tested launching my PythonEngine class using a thread with both
ApartmentState.STA and MTA but this has no discernible effect.

Can you offer any explanation, maybe workaround?

Thanks

AndyF.



Dino Viehland wrote:
>
> AndyF wrote:
>> Hi Chaps
>>
>> I have attempted to purloin some of the code shipped with IP in Action
>> and,
>> following issues, I have even gone to the lengths of reading the book!
>>
>> I am getting the error 'expect Delegate, got Function' when I use the
>> following code. FYI I am passing in a reference to a WPF textBox so I
>> should
>> have a dispatcher on my UI element
>>
>> I have removed all of the threading pipe reading stuff just to leave
>> 'test'
>> code:
>>
>> import System
>> import System.IO
>> import Avacta.Optim.Server.WebServices
>> import Avacta.Optim.Server.DataModel
>> import sys
>> import clr
>> import time
>>
>> from System import Console
>> from System.Threading import Thread, ThreadStart
>>
>> def SetDispatcher(ui_element):
>> global dispatcher # needed else "Exception: 'NoneType' object has no
>> attribute 'BeginInvoke'"
>> dispatcher = ui_element.Dispatcher
>>
>> def Dispatch(function, *args):
>> dispatcher.BeginInvoke(lambda *_: function(*args))
>>
>> def GetDispatchFunction(function):
>> return lambda *args: Dispatch(function, *args)
>>
>> class ListOutput:
>> def __init__(self, textbox):
>> self.textbox = textbox
>>
>> def write(self, string):
>> Dispatch(self.addText, string) # error: "expect Delegate, got Function"
>> # self.addText(string) # ok works fine w-w/o dispatcher stuff
>>
>> def addText(self, string):
>> textbox.AppendText(string)
>>
>> if textbox != None:
>> listout = ListOutput(textbox)
>> sys.stdout = listout
>> SetDispatcher(textbox)
>>
>> print "Define running"
>> #running = True
>>
>> Thread.Sleep(0)
>> time.sleep(2)
>>
>> print "Start The Comms Thread..."
>> #comms_t = Thread(ThreadStart(run_comms))
>> #comms_t.Start()
>>
>> Thread.Sleep(0)
>> time.sleep(2)
>>
>> Any clues would be greatly appreciated!
>
> The WPF invocation functions just take a type which is typed to "Delegate"
> instead of a type of a specific delegate.  Therefore we don't know what
> type
> of delegate to create for you automatically.  Instead you can convert the
> Python function into a delegate by calling the delegate type directly,
> e.g.:
>
> dispatcher.BeginInvoke(System.Action(lambda *_: function(*args)))
>
> or you can use another delegate type (e.g. System.Action[object]) with the
> appropriate signature you need.
>
>
> _______________________________________________
> Users mailing list
> [hidden email]
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>
>

--
View this message in context: http://old.nabble.com/Dispatcher-Problem-tp31782357p31789855.html
Sent from the IronPython mailing list archive at Nabble.com.

_______________________________________________


_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com