Is there any library class I can use for a buffer in a consumer-producer situation with multiple threads?
I don't very well understand the multithreading ways of C# so thew example of a perfect solution is in Java:
//Thread 1
Buffer buf = new Buffer();
Thread t2 = new Thread(new MyRunnable(buf) );
while(true){
buf.put(foo);
}
}
//MyRunnable
private Buffer buf;
public MyRunnable(Buffer buf){
this.buf = buf;
}
public void run(){
while(!buf.IsFinished()){
foo = buf.take();
dosth(foo);
}
}
System.Collection.Concurrent has a number of implementations of the IProducerConsumerCollection<T> interface (e.g. ConcurrentQueue<T>), which may be of use in your situation.
There is also a BlockingCollection<T> class that lets your thread block while waiting for the input.
You could use .NET 4.0's ConcurrentBag<T> for this. It implements IProducerConsumerCollection<T> which is designed for that.
If order matters, you can look at ConcurrentQueue<T> or ConcurrentStack<T>.
It looks like you're just trying to find a way to do some work in a background thread and pass collected data off to the caller?
You could use the BackgroundWorker class for this. It allows you to create a simple background thread and pass off something back to the caller when you're done.
public class TestClass
{
private BackgroundWorker worker;
public void DoSomeWorkAsync()
{
this.worker = new BackgroundWorker();
this.worker.DoWork += this.OnDoWork;
this.worker.RunWorkerCompleted += this.OnWorkerComplete;
this.worker.RunWorkerAsync();
}
private void OnDoWork(object sender, DoWorkEventArgs e)
{
//do long running process here to pass to calling thread.
//note this will execute on a background thread
DataTable DT = GetSomeData();
e.Result = DT;
}
private void OnWorkerComplete(object sender, RunWorkerCompletedEventArgs e)
{
//note this event is fired on calling thread
if (e.Error != null)
//do something with the error
else if (e.Cancelled)
//handle a cancellation
else
//grab the result
foo = e.Result;
}
}
Related
My question is i want to execute some operations like fetching the data ( format is string )from some URL . and i want run this process to be background. i have to call this operations whenever user needs this. like if a user clicks a button specified for this operation, it should execute the function and provide result to that user. Problem is when ever executing this no other program should not get interrupted. I want to run this Asynchronous way . i want to return the result which is downloaded from the URL
Here is my solution using thread
namespace xyz
{
public class newWinForm : Form
{
SomeClass someClass = new SomeClass();
public newWinForm()
{
Thread backgroundThread = new Thread(DoWork);
backgroundThread.IsBackground = true;
backgroundThread.Start();
}
void DoWork()
{
try
{
Console.WriteLine("Doing some work...");
using(WebClient cl = new WebClient())
{
string result = cl.DownloadString("http://www.......com");
}
Thread.Sleep(1000);
}
finally
{
Console.WriteLine("This should be always executed");
}
}
private void getDataFrmUrlButton_Click(object sender, EventArgs e)
{
Thread backgroundThread = new Thread(DoWork);
backgroundThread.IsBackground = true;
backgroundThread.Start();
}
}
You can use backgroundworker class in order to achieve your task
private BackgroundWorker bg1 = new BackgroundWorker();
bg1.DoWork += bg1_DoWork;
private void bg1_DoWork(object sender, DoWorkEventArgs e)
{
//the function you want to execute
}
In this case your operation is I/O bound, so an asynchronous approach is best. To do this you can use the async keyword on your events.
private async void getDataFrmUrlButton_Click(object sender, EventArgs args)
{
using(var client = new WebClient())
{
string result = await client.DownloadStringTaskAsync(uri);
// Do stuff with data
}
}
This post gives some good resources for more information on async/await.
If you want a more enterprise based solution you can have a look at Hangfire (https://www.hangfire.io/).
While normally targeted at ASP.NET solutions you can also run it as part of a windows service and use that in conjunction with your WinForm based application(s). It will allow you to easily hand off long running tasks and track them even if you don't want to to use TPL to do it yourself.
Assuming the constructive criticism in this thread Thread-safe events - is this a "clean" way? I sat down and tried to read me in the whole thematics of multithreading.
Here's some code with the same base question: Is this an established way to create a non-freezing UI using events?
public partial class Form1 : Form
{
public delegate void MyThreadUpdateHandler(string s);
public event MyThreadUpdateHandler MyThreadUpdate;
System.Threading.Thread MyThread;
public Form1()
{
InitializeComponent();
}
void DoTheCount()
{
int a = 0;
while (a < int.MaxValue)
{
if (a % 1000000 == 0)
{
this.MyThreadUpdate(a.ToString());
}
a++;
}
}
private void Form1_MyThreadUpdate(string s)
{
this.lblEvent.Invoke((MethodInvoker) delegate ()
{
lblEvent.Text = s;
});
}
private void btnStartThread_Click(object sender, EventArgs e)
{
MyThreadUpdate += Form1_MyThreadUpdate;
if (MyThread == null)
MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(DoTheCount));
lblStatus.Text = "Starting thread";
if (MyThread.ThreadState == System.Threading.ThreadState.Unstarted)
MyThread.Start();
}
private void btnAbortThread_Click(object sender, EventArgs e)
{
MyThread.Abort();
}
}
However there's something I still don't get. Why are some examples using a Program() like this one? http://www.codeproject.com/Articles/667298/Using-ThreadStaticAttribute
Thank you :)
However there's something I still don't get. Why are some examples
using a Program() like this one?
http://www.codeproject.com/Articles/667298/Using-ThreadStaticAttribute
the code is
static void Main(string[] args)
{
Program prog = new Program();
//define the threads
Thread thread1 = new Thread(new ThreadStart(prog.ThreadFunc1));
Thread thread2 = new Thread(new ThreadStart(prog.ThreadFunc2));
This allowed the developer to call instance funcitons public void ThreadFunc1() & public void ThreadFunc2()
from static funciton - static void Main(string[] args)
Update 1
Established way to create a non-freezing UI, is to do all the time consuming activity on a separate thread & marshal the call to UI thread only to update to it.
What you have implemented follows the same idea.
Just one point I would like to mention, although it has nothing to do with freezing of UI.
instead of System.Threading.Thread, Please use ThreadPool.
Task, BackgroundWorker, System.Threading.Timer, Asynchronous Programming Model all use a thread from ThreadPool. or you may also use ThreadPool.QueueUserWorkItem
There are very special cases when one should use System.Threading.Thread instead of a thread from ThreadPool
Firstly, let me say, I feel sorry for you, trying to work with a legacy library.
Okay. You qualify for one of the few reasons I would work with threading in .net
Running a Legacy library for a long time
Now, reading your previous code, I feel that you want to use Rx.Net for project.
I would start by creating a IObservable for your library.
public static class LibraryHelper
{
public static IObservable<EventPattern<StatusChangedEventArg>> StatusObservable(this ComLibrary com)
{
return Observable.FromEventPattern<EventHandler<StatusChangedEventArg>, StatusChangedEventArg>(x => com.FooEvent +=x, x => com.FooEvent -= x);
}
}
This shall allow you to use Rx.Net with your library, like so...
private async void btnStartThread_Click(object sender, EventArgs e)
{
ComLibary com = new ComLibray();
lblStatus.Text = "Starting thread";
// using is there to unsubscribe after the call, to prevent a memory leak.
var subscription = com.StatusObservable()
//Magic sauce
//http://stackoverflow.com/questions/7417978/how-to-get-a-winform-synchronization-context-or-schedule-on-a-winform-thread
.ObserveOn(SynchronizationContext.Current)
.Subscribe(#event => {
//Do something on the UI thread
});
using(subscription)
{
//Task.Run uses a background thread to get the data from your COM
var result = await Task.Run(()=> com.Read());
//back in UI thread. Do stuff.
}
}
I have noticed that as the database of my application has grown, the time taken to return results has also increased. In the beginning this was negligible because it was such a small amount of time to return the data source.
Now I am at the point where it temporarily makes the UI unresponsive for a couple of seconds, but I would like to create background workers to do these tasks.
The problem with creating these, is that there are around 9 buttons that would need a background worker and all they do is call a different method in the DLL. Is there any way to use a common method to create these background workers using the API for background workers or should I create an Enum that corresponds to each button and is a parameter taken in by the method that constructs the background worker. Thus meaning I could use a simple switch to execute whatever method from the DLL I choose?
Sample Code:
void bg_DoWorkImports(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
try
{
e.Result = EngineBllUtility.GetNotImportedFiles(connectionString);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void bg_RunWorkerCompletedImports(object sender, RunWorkerCompletedEventArgs e)
{
DataSet temp = (DataSet)e.Result;
if (e.Result != null)
{
importFileGridView.DataSource = temp.Tables[0];
}
}
You could pass an Func<T> to a method that creates a BackgroundWorker and call that action from within to DoWork-event.
Something like this
public class BackgroundWrapper<T>
{
private Func<T> workMethod;
private Action<T> completeMethod;
public static void StartBackgroundworker(Func<T> workMethod, Action<T> completeMethod)
{
BackgroundWrapper<T> bWrap = new BackgroundWrapper<T>();
bWrap.workMethod = workMethod;
bWrap.completeMethod = completeMethod;
bWrap.Start();
}
private void Start()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
completeMethod((T)e.Result);
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = workMethod();
}
}
Instead of using BackgroundWorker, an alternative would be to use the TPL. This would let you write the code directly within each member:
void buttonImport_Click(object sender, DoWorkEventArgs e)
{
Task.Factory
.StartNew( () => return EngineBllUtility.GetNotImportedFiles(connectionString))
.ContinueWith( t =>
{
try
{
if (t.Result != null)
{
importFileGridView.DataSource = t.Result.Tables[0];
}
}
catch (AggregateException ex)
{
MessageBox.Show(ex.InnerException.Message);
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Sure, I don't see why you couldn't create a "switchboard" sort of function for that. In fact, you might want to do that, because it would make things a little more modular and promote code reuse.
As far as enums go, personally, I create classes to pass lots of arguments in and out of such things.
I think you need to build some kind of queuing mechanism where one background worker picks up each of the button click jobs and kicks off one after other.
I have a program that makes some hefty calls to the database and then updates the UI. This is causing problems because for most of the time it means that the UI in not responsive. I therefore decided that I wanted to put the function calls that access the database and update the UI in a separate thread, so now I have something like this:
private delegate void CallAsyncDelegate();
private void CallGetDBValues()
{
// Call GetDatabaseValues in new thread
CallAsyncDelegate callGetDatabaseValues = new
CallAsyncDelegate(GetDatabaseValues);
BeginInvoke(callGetDatabaseValues);
}
private void GetDatabaseValues()
{
// Get lots of data here
// Update UI here
}
...
However, it seems to make no difference whatsoever to the UI. I read somewhere that if the code to be run in a separate thread needed to update the UI then this was how the call should be made - is this correct? Am I doing something wrong?
You may be better served using the BackgroundWorker that is built-in to the .NET framework.
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.WorkerReportsProgress = true;
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// update UI with status
label1.Text = (string)e.UserState
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Check for cancel
if(e.Cancelled)
{
//Handle the cancellation.
{
//Check for error
if(e.Error)
{
//Handle the error.
}
// Update UI that data retrieval is complete
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
// Get data
//foreach to process data
//Report progress
bw.ReportProgress(n, message);
}
Here's a link to the MSDN article on how to use the BackgroundWorker for additional details. Thanks to Henk Holterman for the suggestion to include this:
http://msdn.microsoft.com/en-us/library/cc221403%28VS.95%29.aspx
In the "// Update UI here", make sure to use Control.Invoke to actually do the work -- it's imperative that the UI only be "touched" by the UI-thread, and this only happens when you use Control.Invoke.
BeginInvoke and Invoke means to run the code on the UI thread. In this case if you are calling CallGetDBValues() from the UI thread you are not going to gain anything.
Usually you will create a BackgroundWorker or background thread that will do the heavy lifting and it will Invoke back to the UI thread the values that need to be updated.
A BackgroundWorker will probably be the better solution (see Robaticus's answer), but here is a background thread version.
private delegate void CallAsyncDelegate();
private void button_Click( object sender, EventArgs e )
{
Thread thread = new Thread( GetDBValues );
thread.IsBackground = true;
thread.Start();
}
private void GetDBValues()
{
foreach( ... )
{
Invoke( new CallAsyncDelegate( UpdateUI ) );
}
}
private void UpdateUI()
{
/* Update the user interface */
}
I'm not sure of the syntax.. but the sytax I'm more familiar with is something like:
public delegate object myDelegate(object myParam);
Public class MyClass
{
public static void Main()
{
myDelegate d = new myDelegate(myMethod);
d.BeginInvoke ( new object() );
}
static void myMethod(object myParam)
{
// do some work!!
return new object);
}
}
I have a lengthy user-interface operation on my form which is triggered whenever an event is fired. Rather than have the UI block while the operation takes place, I'd like to perform the operation in another thread, and abort that thread and start again if the event fires again.
However, to safely alter controls on my form, I need to use the form's Invoke or BeginInvoke methods. If I do that, then I could put all my UI operations in one function like this:
private delegate void DoUIStuffDelegate(Thing1 arg1, Thing2 arg2);
private void doUIStuff(Thing1 arg1, Thing2 arg2)
{
control1.Visible = false;
this.Controls.Add(arg1.ToButton());
...
control100.Text = arg2.ToString();
}
...
private void backgroundThread()
{
Thing1 arg1 = new Thing1();
Thing2 arg2 = new Thing2();
this.Invoke(new DoUIStuffDelegate(doUIStuff), arg1, arg2);
}
Thread uiStuffThread = null;
public void OnEventFired()
{
if (uiStuffThread != null)
uiStuffThread.Abort();
uiStuffThread = new Thread(backgroundThread);
uiStuffThread.Start();
}
but if I do that, then I lose the benefit of working in a separate thread. Alternatively, I could put them each in their own function like this:
private delegate void DoUIStuffLine1Delegate();
private delegate void DoUIStuffLine2Delegate(Thing1 arg1);
...
private delegate void DoUIStuffLine100Delegate(Thing2 arg2);
private void doUIStuffLine1()
{
control1.Visible = false;
}
private void doUIStuffLine2()
{
this.Controls.Add(arg1.ToButton());
}
...
private void doUIStuffLine100(Thing2 arg2)
{
control100.Text = arg2.ToString();
}
...
private void backgroundThread()
{
Thing1 arg1 = new Thing1();
Thing2 arg2 = new Thing2();
this.Invoke(new DoUIStuffLine1Delegate(doUIStuffLine1));
this.Invoke(new DoUIStuffLine2Delegate(doUIStuffLine2), arg1);
...
this.Invoke(new DoUIStuffLine100Delegate(doUIStuffLine100), arg2);
}
Thread uiStuffThread = null;
public void OnEventFired()
{
if (uiStuffThread != null)
uiStuffThread.Abort();
uiStuffThread = new Thread(backgroundThread);
uiStuffThread.Start();
}
but that's a horrible, unmaintainable mess. Is there a way to create a thread that can modify the user interface, and that I can abort? So that I can just do something like this:
private void doUIStuff()
{
Thing1 arg1 = new Thing1();
Thing2 arg2 = new Thing2();
control1.Visible = false;
this.Controls.Add(arg1.ToButton());
...
control100.Text = arg2.ToString();
}
Thread uiStuffThread = null;
public void OnEventFired()
{
if (uiStuffThread != null)
uiStuffThread.Abort();
uiStuffThread = this.GetNiceThread(doUIStuff);
uiStuffThread.Start();
}
without having to disable cross-thread checks on my form? Ideally I'd like to be able to set some attribute on the thread or the method which individually wrapped all of the operations in delegates that then got invoked on the form's thread.
First - don't disable the cross-thread checks... forms have thread affinity...
Second - try to avoid aborting threads; it isn't nice - you should prefer clean shutdown (such as the cancellation that BackgroundWorker supports)
One option might be to write a wrapper method that:
accepts a typed delegate (so you can call it more simply)
does the necessary checking (throwing an exception to terminate and unroll)
For example:
void worker_DoWork(object sender, DoWorkEventArgs e)
{
try {
Action<Action> update = thingToDo =>
{
if (worker.CancellationPending) throw new SomeException();
this.Invoke(thingToDo);
};
//...
string tmp = "abc"; // long running
update(() => this.Text = tmp);
tmp = "def"; // long running
update(() => textbox1.Text = tmp);
} catch (SomeException) {
e.Cancel = true;
}
}
This is still a little messy, but arguably cleaner than aborting threads left and right...
You can avoid the use of Invoke using the object SynchronizationContext that was introduced in framework 2. Ok , it's the same thing, you substitute one thing for another, but in fact, it is more efficient and robust.
Anyway, cross-threads need checks, because you can never access a control created in another thread without this.
Read about this in:
http://www.codeproject.com/KB/cpp/SyncContextTutorial.aspx
http://codingly.com/2008/08/04/invokerequired-invoke-synchronizationcontext/
Some code to expose my idea:
private Thread workerThread;
private AsyncOperation operation;
public event EventHandler SomethingHappened;
public MySynchronizedClass()
{
operation = AsyncOperationManager.CreateOperation(null);
workerThread = new Thread(new ThreadStart(DoWork));
workerThread.Start();
}
private void DoWork()
{
operation.Post(new SendOrPostCallback(delegate(object state)
{
EventHandler handler = SomethingHappened;
if(handler != null)
{
handler(this, EventArgs.Empty);
}
}), null);
operation.OperationCompleted();
}
I answer you here because comments are too short.
I personally use BackgroundWorker and when the method finishes, the thread is liberated. Basically what you do is:
bw = new BackgroundWorkerExtended();
bw.DoWork += (DoWorkEventHandler)work;
bw.WorkerSupportsCancellation = true;
//bw.WorkerReportsProgress = true;
bw.RunWorkerCompleted += (RunWorkerCompletedEventHandler)workCompleted;
//bw.ProgressChanged+=new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerAsync();
Another thing if you use Post, it will be asynchronous, if you use, Send it would be synchronous.
To cancel:
bw.CancelAsync();
Further to the BackgroundWorker suggestion and the associated comment, BackgroundWorker does marshal the OnProgress callback back onto the UI thread, so you CAN update stuff from there without needing to do Invoke().
I can't really tell whether that's helpful or not, and anyway it's a technique you could use pretty easily without background worker.
I suspect that if the background task needs to know so much about the form that it is doing a bazillion invokes, then you might have a separation-of-concerns issue that would be worth thinking about anyway.