I have multiple threads writing to WebBrowser (using a function that
checks InvokedRequired , and if so, invokes itself on the WebBrowser
thread) and they are getting deadlocked.
They only deadlock when I use lock { } around the call to
WebBrowser.Writ e to ensure thread safety!
Does any one have experience with such a thing?
Zytan 18 6866
Zytan <zy**********@g mail.comwrote:
I have multiple threads writing to WebBrowser (using a function that
checks InvokedRequired , and if so, invokes itself on the WebBrowser
thread) and they are getting deadlocked.
They only deadlock when I use lock { } around the call to
WebBrowser.Writ e to ensure thread safety!
Does any one have experience with such a thing?
Hang on - do you mean you've already got a lock when you call Invoke?
Could you post a short but complete program which demonstrates the
problem?
See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
--
Jon Skeet - <sk***@pobox.co m> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Zytan wrote:
I have multiple threads writing to WebBrowser (using a function that
checks InvokedRequired , and if so, invokes itself on the WebBrowser
thread) and they are getting deadlocked.
They only deadlock when I use lock { } around the call to
WebBrowser.Writ e to ensure thread safety!
Using 'lock' doesn't make sense.
WebBrowser is a WinForms control, and should only be accessed from its
UI thread. So, if you use Control.InvokeR equired, and properly use
Control.Invoke or Control.BeginIn voke to marshal your call over to the
UI control, you don't need to use 'lock', because all code that touches
the WebBrowser control is serialized on its UI thread.
Access to Control.InvokeR equired is not required to be synchronized - in
fact, it would be easy to deadlock if it and its ilk did require
synchronization . Similarly, Control.Invoke, Control.BeginIn voke etc.
don't require synchronization - check docs for Control.InvokeR equired.
-- Barry
-- http://barrkel.blogspot.com/
Zytan wrote:
I have multiple threads writing to WebBrowser (using a function that
checks InvokedRequired , and if so, invokes itself on the WebBrowser
thread) and they are getting deadlocked.
They only deadlock when I use lock { } around the call to
WebBrowser.Writ e to ensure thread safety!
Does any one have experience with such a thing?
Well if you do:
class Foo
{
//Some stuff to setup a WebBrowser control called WebBrowser
public void SomeMethod()
{
lock(WebBrowser )
{
if(InvokeRequir ed)
{
Invoke(new SomeDelegate(So meMethod));
} else {
//Do something
}
}
}
}
This will result in a deadlock when called from a thread other than the
UI thread. Instead, you should do:
class Foo
{
//Some stuff to setup a WebBrowser control called WebBrowser
public void SomeMethod()
{
if(InvokeRequir ed)
{
Invoke(new SomeDelegate(So meMethod));
} else {
lock(WebBrowser )
{
//Do something
}
}
}
}
}
If you want more than that, post some code :-)
Alun Harford
Hang on - do you mean you've already got a lock when you call Invoke?
Yes.
Could you post a short but complete program which demonstrates the
problem?
Ok, I made a small program that does nothing but start a timer that
ticks every second. It calls MyWriteLine. This calls (using
InvokeRequired + Invoke, if needed) WebBrowser.Docu ment.Write. (Well,
it makes sure the WebBrowser has a Document to write to, and if not,
navgiates to "about :blan k" first).
Then, I made a thread that I can start/stop with two buttons, this
thread does the same thing as the timer. The stop button calls
myThread.Join() ; to wait for the thread to complete.
Starting the thread is fine, they both update te WebBrowser. Stopping
the thread hangs on myThread.Join() ;
I thought this is a problem with synchronization , so I made a wrapper
to MyWriteLine, and placed a critical section lock into. Thus,
MyWriteLine is only called within a critical section. Now, the
program hangs at the lock statement when I stop the thread.
I'd post the code, but I don't have it with me at the moment. I'll
code it again, and do some more testing. I have a feeling that
replacing WebBrowser with another control solves the problem.
Zytan
WebBrowser is a WinForms control, and should only be accessed from its
UI thread. So, if you use Control.InvokeR equired, and properly use
Control.Invoke or Control.BeginIn voke to marshal your call over to the
UI control, you don't need to use 'lock', because all code that touches
the WebBrowser control is serialized on its UI thread.
Ok, I knew that Control.Invoke made the call on the same thread as
Control, but, I am unaware of what it's doing internally. I don't
know what 'marshal' actually means. So, it basically means it is
serialized on the Control's thread, meaning that all calls to
Control.Invoke are called in order, one after the other, and thus
multiple threads all calling Control.Invoke to update a single control
will be safe.
Access to Control.InvokeR equired is not required to be synchronized - in
fact, it would be easy to deadlock if it and its ilk did require
synchronization . Similarly, Control.Invoke, Control.BeginIn voke etc.
don't require synchronization - check docs for Control.InvokeR equired.
Ok, thanks, Barry
Zytan
Well if you do:
>
class Foo
{
//Some stuff to setup a WebBrowser control called WebBrowser
public void SomeMethod()
{
lock(WebBrowser )
{
if(InvokeRequir ed)
{
Invoke(new SomeDelegate(So meMethod));
} else {
//Do something
}
}
}
}
Ha ha, yes, I wasn't stupid enough to recusively attempt to enter the
same lock. The lock I have is in a wrapper around SomeMethod().
If you want more than that, post some code :-)
I will once I make my small source example again.
Zytan
Code example: Make two Buttons (btnStart, btnStop), and one
WebBroswer (webLog), and paste this into the main Form:
Thread myThread;
private volatile bool m_ThreadProcess ing = false;
private int m_count = 0;
private void ThreadFunc()
{
while (m_ThreadProces sing)
{
Thread.Sleep(40 0);
m_count++;
MyWrite(webLog, m_count + "<br>" +
Environment.New Line);
}
}
private void btnStart_Click( object sender, EventArgs e)
{
if (myThread == null)
{
myThread = new Thread(ThreadFu nc);
m_ThreadProcess ing = true;
myThread.Start( );
}
}
private void btnStop_Click(o bject sender, EventArgs e)
{
if (myThread != null)
{
m_ThreadProcess ing = false;
myThread.Join() ; // <------------- HANGS HERE!
myThread = null;
}
}
delegate void MyWrite_Delegat e(WebBrowser web, string str);
public static void MyWrite(WebBrow ser web, string str)
{
if (web.InvokeRequ ired)
{
MyWrite_Delegat e funcptr = MyWrite;
object[] args = { web, str };
web.Invoke(func ptr, args);
}
else
{
if (web.Document == null) web.Navigate("a bout:blank");
web.Document.Wr ite(str);
web.Document.Wi ndow.ScrollTo(0 , int.MaxValue); //
scroll to bottom
}
}
Note that this hangs only with this single thread accessing the
WebBrowser. Not even the main thread accesses it! (I'm preparing for
you guys to show me the obvious error I've been missing all day.)
Zytan
On Apr 3, 4:49 pm, "Zytan" <zytanlith...@g mail.comwrote:
Code example: Make two Buttons (btnStart, btnStop), and one
WebBroswer (webLog), and paste this into the main Form:
<snip>
Yes, that would hang. You're using "Invoke" from myThread - that will
block until the delegate you've passed it has been executed on the UI
thread.
Now, from the UI thread, you're calling myThread.Join - that will
block until myThread has completed.
So, how can either of them get anywhere?
Jon
Yes, that would hang. You're using "Invoke" from myThread - that will
block until the delegate you've passed it has been executed on the UI
thread.
Now, from the UI thread, you're calling myThread.Join - that will
block until myThread has completed.
Ok, it's a deadlock.
I was uncertain as what happened as a result of Invoke. Thanks to
your reply, I have a better idea. The message queue in the main
thread is processing the 'stop button clicked' message, which is
running Thread.Join, which is waiting for myThread to terminate. The
message queue is stalled (never a good idea).
myThread is upset that it doesn't own the control (as it shouldn't,
since it doesn't have a message queue to maintain it), so it tells the
GUI thread to deal with it, via Invoke. Now, my understanding is that
Invoke is *not a function pointer call* (perhaps this is why they call
them delegates, instead of function pointers?), it is a message placed
in the GUI thread. (This is why an earlier post mentioned that
Control.Invoke is serialized, meaning they are handled one at a time,
because the message queue processes one message at a time. So, if
multiple threads posted multiple messages into the queue, it still
does one at a time, and my WebBrowser doesn't need a critical
section.) But, the GUI thread has its message queue stalled.
Solution #1: Use BeginInvoke, which is a 'non blocking' call (it must
call Win32's PostMessage instead of SendMessage).
Solution #2: Don't use Thread.Join(). The examples show it, so I
used it. Often, it is unneeded.
Solution #3: Don't make the worker threads access the GUI.
Solution #4: Use BackgroundWorke r, which I presume doesn't have this
issue (I think it calls a function of yours when it is done, so you
never have to call something like BackgroundWorke r.Join, which likely
doesn't exist).
Does that all make sense?
Zytan This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Lad |
last post by:
I would like to use httplib/urllib to download webpages from 3
different websites.From my script
I want to open 3 webbrowser windows( 3 threads) and open in each
thread( window) pages from a particular website.
Is it possible to do that in Python?
Thanks for help
Lad
|
by: Guyon Morée |
last post by:
If I have multiple threads reading from the same file, would that be a
problem?
if yes, how would I solve it?
Let's say I want to take it a step further and start writing to 1 file form
multiple threads, how would I solve that?
thanx,
|
by: Tony Liu |
last post by:
Hi, how can I create multiple new file handles of a file without having to
share to file to the other processes?
I have a file that will be accessed by multiple threads in my application,
each time a thread try to do something with the file, the thread will create
a new file handle. However, if I specify FileShare.ReadWrite, other process
can also open that file. I tried FileShare.Inheritable but it doesn't work.
The reason I needs to...
|
by: tshad |
last post by:
Can you do a search for more that one string in another string?
Something like:
someString.IndexOf("something1","something2","something3",0)
or would you have to do something like:
if ((someString.IndexOf("something1",0) >= 0) ||
((someString.IndexOf("something2",0) >= 0) ||
|
by: RahimAsif |
last post by:
Hi guys,
I would like some advice on thread programming using C#.
I am writing an application that communicates with a panel over
ethernet, collects data and writes it to a file. The way the data is
collected is that we have different schedules (so one set of data is
collected say every second, another set of data might be collected
every 30 seconds, and so on).
| |
by: cj |
last post by:
As many of you know I'm writing a TCP/IP server with multiple threads
handling multiple short conversations (submit a short string, send back
a sort string). Threads are created as needed to handle a new
connection request and terminate after the exchange is complete.
I got a new request for the program. I've been asked the the program
write all the strings it receives and sends to a log file. I'm
concerned about all these threads...
|
by: Olie |
last post by:
This post is realy to get some opinions on the best way of getting fast
comunication between multiple applications. I have scowered the web for
imformation on this subject and have just found conflicting views and
far from ideal solutions.
My application has to send small amounts of data about 50bytes to
multiple client applications. The catch is that this has to happen
about 1000 times a second.
My first attempt was .net remotting...
|
by: PAzevedo |
last post by:
I have this Hashtable of Hashtables, and I'm accessing this object from
multiple threads, now the Hashtable object is thread safe for reading,
but not for writing, so I lock the object every time I need to write to
it, but now it occurred to me that maybe I could just lock one of the
Hashtables inside without locking the entire object, but then I thought
maybe some thread could instruct the outside Hashtable to remove an
inside Hashtable...
|
by: scriptlearner |
last post by:
OS: Solaris 9
Python Version: 2.4.4
I need to log certain data in a worker thread; however, I am getting
an error now when I use two worker threads.
I think the problem comes from the line
logging.info('Thread Object (%d):(%d), Time:%s in seconds %d'%
(self.no,self.duration,time.ctime(),time.time()))
when multiple worker thread is trying to update the log files.
What did I do wrong? Should I lock the log file before writing to
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| | |