I asked a similar question here; thanks to everyone who provided suggestion! However, it seems that my problem is bigger than the one described above, so I am posting a new question.
The issue is that I need to keep my UI responsive when I am loading a large document using a third party control called document
. The document
is a class embedded in a third party control, ther开发者_如何学编程e is no way for me to new it, and it doesn't have Invoke
function.
I am trying to use Backgroundworker
for this. The code I try is of this form:
public class MyForm: Form
{
private delegate bool OpenFile(string filePath);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
OpenFile oF = new OpenFile(document.Open);
var openFile = this.Invoke(oF, MyFileName);
e.Result = openFile;
}
}
Now, in the UI thread, where document
belongs, when it is doing the Open
operation, a dialog box is supposed to come up and updating itself and the main thread is supposed to remain responsive ( i.e., I can still drag and drop the form anyway I like). This is what I was trying to accomplish.
The problem is that the above code will make both of my threads ( the main UI thread and the dialog box thread) hang during the time of loading. My question is,is there anyway to fix this issue?
P/S: I have tried var openFile = Invoke(oF, MyFileName)
and var openFile = BeginInvoke(oF, MyFileName)
and var openFile = OtherControl.Invoke(oF, MyFileName)
, all didn't help.
Your included example doesn't show quite enough to clearly identify the problem. My assumption is that your class doesn't contain an explicit Invoke()
method, so your example is calling Form.Invoke()
. If that's the case then you're misunderstanding the purpose of that method.
Form.Invoke()
ensures that the included delegate is executed on the UI thread. Therefore your background thread isn't actually doing the work, instead your background thread is returning to your UI thread prior to executing the delegate... hence the unresponsive UI.
You might be the victim of an unfortunate ambiguity... both System.Delegate
and System.Windows.Forms.Form
& Control
contain methods named Invoke()
and BeginInvoke()
but serve different purposes. Unfortunately this is where your sample is a little incomplete. Is OpenFile
a delegate? Does your class contain an explicit Invoke()
method?
Update: After some discussion in the comments the feasible options were whittled down to either:
Trying to preload the data to a temporary in-memory location on a background thread, then loading the 3rd Party UI control from that location versus from the filesystem/network
Using .NET Reflector to examine the internal/non-public API of the control and attempt to use Reflection to override the current behavior by calling non-public methods or setting fields/properties
Older question, but no answer marked as being right so I asume the problem wasn't solved by the current answers.
I had a problem with the same symptoms. Using a background worker thread the UI bacame non-responisve.
I basically followed the follwoing tutorials: http://msdn.microsoft.com/en-us/library/hybbz6ke.aspx http://broadcast.oreilly.com/2010/06/understanding-c-using-backgrou.html
Reported some progress and got stuck with a non responsive UI. Turned out I was giving to much to fast progress and just updating the progress made my UI responsive. Changing the number of progress updates to one for every thousend items solved my problem.
Hope this helps.
精彩评论