All,
I wish to write a plugin .dll to be used/called by a .NET application called at runtime. My .dll is a WinForm and displays the (computationally expensive) operations being undertaken. The .dll is called from the main application are invoked via .NET System.Reflection
. I have to provide to the calling application the NameSpace, Class and the Method I want to invoke.
I would like to multi-thread my .dll so that it is more UI friendly and I am only really familiar with BackgroundWorker
s.
EDIT: Extension to question.
So, I call the .dll as follows:
if (classType != null)
{
if (bDllIsWinForm)
{
classInst = Activator.CreateInstance(classType);
Form dllWinForm = (Form)classInst;
dllWinForm.Show();
// Invoke required method.
MethodInfo methodInfo = classType.GetMethod(strMethodName);
if (methodInfo != null)
{
object result = null;
// The method being called in this example is 'XmlExport'.
result = methodInfo.Invoke(classInst, new object[] { dllParams });
return result.ToString();
}
}
else
{
// Else not a WinForm do simalar.
}
}
So then in the WinForm .dll I want to multi-thread the time consuming work so that I can display what is going on. So in the .dll, using BackgroundWorker
I have:
BackgroundWorker bgWorker; // Global.
public string XmlExport(object[] connectionString)
{
try
{
bgWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged);
bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
// Wait until workerThread is done.
threadDoneEvent = new AutoResetEvent(false);
bgWorker.RunWorkerAsync();
threadDoneEvent.WaitOne();
return strResult; // Global String strResult
}
catch (Exception)
{
throw;
}
}
Then I have the DoWork
event handler:
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker thisWorker = sender as BackgroundWorker;
strResult = (string)this.XmlExportBgw(ref thisWorker); // Or should I use bgWorker?
e.Result = strResult;
}
public string XmlExportThreaded(ref BackgroundWorker thisWorker)
{
try
{
// Some expesive work...
// UI.
InfoBall infoBall = new InfoBall(); // Class containing processing information.
// Set infoBall parameters here...
(thisWorker as BackgroundWorker).ReportProgress(infoBall.progressBarValue, infoBall);
// Some more expensive work...
// UI.
(thisWorker as BackgroundWorker).ReportProgress(infoBall.progressBarValue, infoBall);
}
//...
}
The `ProgressChanged' event is
void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// UI.
InfoBall someBall = (InfoBall)e.UserState;
// Update process information.
if (someBall.showRichTextBox)
{
this.richTextBox.AppendText(someBall.richTextBoxText);
this.richTextBox.ScrollToCaret();
}
return;
}
In addition to the above code I have the usual RunWorkerCompleted
etc.
The calling application has been written to allow the user to call thereown .NET .dlls at runtime. The .dll I am trying to put together is a time intensive one and one that will only be supplied to particular users. I have run the above code and the problem is that it will not update the user interface correctly. That is that you cannot manipulate (resize, click etc.) the Form
and it does not print and progress information until the very end of the processing when it only prints the final message out multiple times. However, it is correctly producing the .xml files I require. What am I doing wrong? Should I be invoking the .dll method from a separate thread?
Any help would be greatly appreciated. Thanks very much for your time.
I am not sure what kind of methods you are tryng to execute in that dll. I am assuming they are not asynchronous meaning your main thread (application) will stop until they are done executing. An easy example could be demonstrated with the Messagebox.show("myMessage"); method. For example how could you execute 3 message boxes at once? it will not be possible without using multiple threads. Hope this methods helps:
public void SomeMethod()
{
Thread thread = new Thread(new ThreadStart(() =>
{
// this code is going to be executed in a separate thread
MessageBox.Show("hello");
// place additional code that you need to be executed on a separate thread in here
}));
thread.Start();
}
then if I call that method 3 times as:
I will now be running 4 threads on my program. The main thread plus the 3 calls that I created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With