Sleeping Until Property Changes

  • Thread starter Thread starter James Hancock
  • Start date Start date
J

James Hancock

I often have to do a sleep until a property changes in the control I wrote.
Right now I do an Application.DoEvents() on a while loop. (yes, the result
will always occur, it's just a matter of time. The problem with this, is
that the while loop takes up huge processor time, which I don't want.

So what I'm looking for is a way to stop processing in what I"m doing until
the property changes (but allow the rest of the control to continue.)

Anyone have any ideas how I would go about doing something like this?

Thanks,
James Hancock
 
You can start your processing job on another thread (so the UI thread
doesn't get blocked). When your property of the control changes, you can
notify the worker thread that it needs to stop working. I think this is the
"better" solution. It will require some plumbing code for handling the
thread stuff, but actually .NET has some nice built-in threading
functionality. Check your the System.Threading namespace.

If you have further questions, let me know and I'll try to help...
 
* "James Hancock said:
I often have to do a sleep until a property changes in the control I wrote.
Right now I do an Application.DoEvents() on a while loop. (yes, the result
will always occur, it's just a matter of time. The problem with this, is
that the while loop takes up huge processor time, which I don't want.

What does changing the property value have to do with a loop? Just
"wait" in the 'Set' method of the property for a change of its value.
So what I'm looking for is a way to stop processing in what I"m doing until
the property changes (but allow the rest of the control to continue.)

Maybe a thread, but I don't understand how this is related to changing a
property value.
 
In addition to Herfried's post I want to remind that some of the properties
in the control classes fire XXXXChanged events. Those events can be used to
take actions when a property has been changed. That's for standart
properties. For ones that you wrote you can handle changes in the property
*set* accessor as Herfried suggests .

B\rgds
100
 
Hi James,

From my understanding, you want to execute some code when the value of a
certain property changes and the control is also written by yourself.

So is it possible to defind an xxxxChanged event and modify your setter
method of your property like below?

public Atype aProp
{
get {return _aProp;}
set { if (value != _aProp)
{
_aProp = value;
OnaPropChanged(some args);//helper function to make code
clean.
}
}

protected void OnaPropChanged (some params)
{
// define a event (e.g. aPropChanged) in you control
if (aPropChanged != null)
aPropChanged(some params);
}

If you couldn't use this approach, please let us know more detail about
your problem,
thanks!


Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Actually no.

Here's the case.

mshtml returns immediately from setting the document or loading a URL.
That's great, but then you can't do opertations on the loaded document until
the readystate = complete.

Now if you're just doing text html without documents, the complete flag is
fired almost (but not completely) immediately. So what I want to do is when
I set the document, wait for the readystate (an event) is updated to
complete.

So right now I do this:

LoadDocument();

while(doc.ReadyState != "complete")
Application.DoEvents();

But that eats processor time so I want to sleep the thread or something that
doesn't take very much processor time, while the rest of the control keeps
going and the readystate can be fired correctly.

Does that make it any clearer?

James Hancock
 
Hi James,

The mshtml Document object provides an COM event names onreadystatechange,
This event will be fired when there is an changed to the document object,
you may try
handling this event and check the readystate in the event handler , the
readystate should be "completed"
after the document is loaded.
You may handle COM event like this way, also you may take a look at this
link,
http://www.itwriting.com/htmleditor/index.php
Tim Anderson had implemented a HTMLEditor using the mshtml component, maybe
you will get some idea from it.

Thanks, if you have any questions on this issue, please reply to group to
let us know.

<code>
private void button1_Click(object sender, System.EventArgs e)
{
object opt = Type.Missing;
object url = "http://www.google.com";
axWebBrowser1.Navigate2 (ref url,ref opt,ref opt,ref opt,ref opt);
}

private Int32 cookie;
private UCOMIConnectionPoint pConPt;
private void axWebBrowser1_NavigateComplete2(object sender,
AxSHDocVw.DWebBrowserEvents2_NavigateComplete2Event e)
{
if (cookie == 0)
{
mshtml.HTMLDocument doc = (mshtml.HTMLDocument)axWebBrowser1.Document;
UCOMIConnectionPointContainer pConPtCon =
(UCOMIConnectionPointContainer)doc;
Guid guid = typeof(mshtml.HTMLDocumentEvents2).GUID;
pConPtCon.FindConnectionPoint(ref guid, out pConPt);
IEHTMLDocumentEvents d = new IEHTMLDocumentEvents();
pConPt.Advise(d, out cookie);
MessageBox.Show(cookie.ToString());
}
}

public class IEHTMLDocumentEvents : mshtml.HTMLDocumentEvents2
{
public void onactivate(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onafterupdate(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onbeforeactivate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool onbeforedeactivate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onbeforeeditfocus(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onbeforeupdate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void oncellchange(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onclick(mshtml.IHTMLEventObj pEvtObj)
{
MessageBox.Show("click");
return true;
}

public bool onstop(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool onselectstart(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onselectionchange(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onrowsinserted(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onrowsdelete(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onrowexit(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onrowenter(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onreadystatechange(mshtml.IHTMLEventObj pEvtObj)
{
MessageBox.Show("readyStateChange");
}

public void onpropertychange(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onmousewheel(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onmouseup(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmouseover(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmouseout(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmousemove(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool oncontextmenu(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool oncontrolselect(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void ondataavailable(mshtml.IHTMLEventObj pEvtObj)
{
}

public void ondatasetchanged(mshtml.IHTMLEventObj pEvtObj)
{
}

public void ondatasetcomplete(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool ondblclick(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void ondeactivate(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool ondragstart(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool onerrorupdate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onfocusin(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onfocusout(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onhelp(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onkeydown(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onkeypress(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onkeyup(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmousedown(mshtml.IHTMLEventObj pEvtObj)
{
}
}
</code>


Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Just simply make your work into a different class.
Whenever the property changes, you raise an event. In your
application you handle your work after the property
changes in the event.

Jai.
 
Yup, that's what I'm doing. But I'm trying to convert it from an event based
system to a property based one where you can set an HTML property and then
when it returns do anything else you want instead of having to wait for the
Complete.

James Hancock

"Ying-Shen Yu[MSFT]" said:
Hi James,

The mshtml Document object provides an COM event names onreadystatechange,
This event will be fired when there is an changed to the document object,
you may try
handling this event and check the readystate in the event handler , the
readystate should be "completed"
after the document is loaded.
You may handle COM event like this way, also you may take a look at this
link,
http://www.itwriting.com/htmleditor/index.php
Tim Anderson had implemented a HTMLEditor using the mshtml component,
maybe
you will get some idea from it.

Thanks, if you have any questions on this issue, please reply to group to
let us know.

<code>
private void button1_Click(object sender, System.EventArgs e)
{
object opt = Type.Missing;
object url = "http://www.google.com";
axWebBrowser1.Navigate2 (ref url,ref opt,ref opt,ref opt,ref opt);
}

private Int32 cookie;
private UCOMIConnectionPoint pConPt;
private void axWebBrowser1_NavigateComplete2(object sender,
AxSHDocVw.DWebBrowserEvents2_NavigateComplete2Event e)
{
if (cookie == 0)
{
mshtml.HTMLDocument doc = (mshtml.HTMLDocument)axWebBrowser1.Document;
UCOMIConnectionPointContainer pConPtCon =
(UCOMIConnectionPointContainer)doc;
Guid guid = typeof(mshtml.HTMLDocumentEvents2).GUID;
pConPtCon.FindConnectionPoint(ref guid, out pConPt);
IEHTMLDocumentEvents d = new IEHTMLDocumentEvents();
pConPt.Advise(d, out cookie);
MessageBox.Show(cookie.ToString());
}
}

public class IEHTMLDocumentEvents : mshtml.HTMLDocumentEvents2
{
public void onactivate(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onafterupdate(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onbeforeactivate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool onbeforedeactivate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onbeforeeditfocus(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onbeforeupdate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void oncellchange(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onclick(mshtml.IHTMLEventObj pEvtObj)
{
MessageBox.Show("click");
return true;
}

public bool onstop(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool onselectstart(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onselectionchange(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onrowsinserted(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onrowsdelete(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onrowexit(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onrowenter(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onreadystatechange(mshtml.IHTMLEventObj pEvtObj)
{
MessageBox.Show("readyStateChange");
}

public void onpropertychange(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onmousewheel(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onmouseup(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmouseover(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmouseout(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmousemove(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool oncontextmenu(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool oncontrolselect(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void ondataavailable(mshtml.IHTMLEventObj pEvtObj)
{
}

public void ondatasetchanged(mshtml.IHTMLEventObj pEvtObj)
{
}

public void ondatasetcomplete(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool ondblclick(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void ondeactivate(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool ondragstart(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public bool onerrorupdate(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onfocusin(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onfocusout(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onhelp(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onkeydown(mshtml.IHTMLEventObj pEvtObj)
{
}

public bool onkeypress(mshtml.IHTMLEventObj pEvtObj)
{
return true;
}

public void onkeyup(mshtml.IHTMLEventObj pEvtObj)
{
}

public void onmousedown(mshtml.IHTMLEventObj pEvtObj)
{
}
}
</code>


Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed
before
sending.
 
That's exactly what I'm trying to not have happen.

I'm trying to go from an event system (mshtml) to a property system with one
property that returns when everything is done that the event signify.

James Hancock
 
Hi James,

I think another workaround might be add a Sleep call into your while
loop, it will reduce the cpu load.
I also thought if it is possible to use an ManualResetEvent object, and
let your thread wait for the event object set. However I'm not sure how the
mshtml implement the onreadystatechanged (whether it will use the message
loop, if yes, the wait will block the message loop so the event handler
will never be called), you may try this way if you use this COM Component
as in-process.
Hope it helpful, if you have any updates to this problem, please be free
to reply this thread, thanks!

Happy Holidays!

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Thanks! Looks like the sleep is the best suggestion! Yes, the
readstatechanged event doesn't fire if you use the ManualResetEvent object.

Thanks again for all of your help!
James Hancock
 
Back
Top