Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am retrieving data of about 100k rows from a database into a datagridview.This process takes up to 5-6 seconds.however during these seconds the user can't move the mouse or click any other button.how can I use aysnc/multithreading to achieve smooth user interface.
Look into the Task library and async, there's a whole section of C# for doing exactly this.
Basically you wind up with things like . . .
var records = await GetRecordsFromDatabase();
MyDataGridView.ItemSource = records;
private Task<IEnumerable<Record>> GetRecordsFromDatabase(){
return Task.Run(() => {
//do stuff the return IEnumerable<Records>
});
}
Note that while you can use threads, Tasks are a much better option in C# for async support.
Edit - most databases should support some async operation. In that case you'd likely have an async method to transform things from the database to the format you need. You'd also likely want to follow the convention of marking your own method as async. Something like . . . .
private async Task<IEnumerable<Record>> GetRecordsFromDatabaseAsync(){
var dbRecords = await Database.GetRecordsAsync();
//transform the database records and return them
}
And call it as above.
Let's assume you are doing all of this processor intensive work as a result of a button click. Hopefully you already have the work in a separate method and are calling that method from the click event. If you actually have all of your work inside the click event, move it out into its own method and call it from the click event handler.
Now that is still on a single thread. I'll just address using a separate thread here, though you should look into tasks on your own as well. To use a separate thread for the hard work, write 2 lines of code like this:
Thread t = new Thread(nameOfTimeConsumingMethod);
t.Start();
And that will do it. If you need to write output to, say, textBox1, you cannot do so directly from the new thread (no cross thread calls). But you can still write to that box easily enough indirectly like so.
BeginInvoke(new Action(()=>textBox1.text = "Hello world!"));
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 20 days ago.
Improve this question
Say I was making a game and let's pretend I was using a Console Application rather than using something like Unity etc etc.
And imagine I wanted to implement a game loop, the same concept would apply to a dedicated network server for the game.
This is usually how I would have done it, but is this a good option?
public void Start()
{
_isRunning = true;
var sw = new Stopwatch();
while (_isRunning)
{
sw.Start();
/* Update Game Logic */
sw.Stop();
var sleepDelta = Constants.Tickrate - (int)sw.ElapsedMilliseconds;
if (sleepDelta > 0)
Thread.Sleep(sleepDelta);
else
Console.WriteLine(
$"Server can't keep up!\nElapsed: {(int)sw.ElapsedMilliseconds}\nElapsed: {sleepDelta}");
sw.Reset();
}
}
What's the difference between doing that vs something like the Timer and using the OnElapsed event
This is usually how I would have done it, but is this a good option?
Something like this might very well be good enough. I would not expect a high accuracy from the Thread.Sleep, so it might depend on how tight timing requirements you have. For a console based game I would suspect this is not super critical. If you do need high accuracy timers you might want to read this question.
What's the difference between doing that vs something like the Timer and using the OnElapsed event
A timer would do more or less the same thing, but the Threading.Timer/Timers.Timer classes allow ticks to overlap each other if you are not careful, so you either need to be careful with how you are using it, or use something like PeriodicTimer.
You also need a bit careful since the console process will exit when the main method returns, at least for normal non-async main methods.
Timers are in some sense more useful for UI programs where you cannot have a 'main loop', and have specialized timers that run on the UI thread.
But if your method works, then leave it be. If you do not have any problems, chances are that changes will introduce new issues without actually improving anything.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm creating a .net core app where I need to call an async method to process a large number of objects. We have done this within a Parallel.ForEach so we can make use of parallelism to complete the jobs faster.
The service method is an async method which we cannot change. My question is what is the correct way to call this method when using TPL Parallel.
here is a simplified code snippet (i'm passing the iteration # instead of the object for demo purposes), along with our observations:
the CallSendAsync method internally makes a HTTP Request to an API (using HttpClient).
private void ParallelFor()
{
Parallel.For(0, 100000, i =>
{
CallSendAsync(i).GetAwaiter().GetResult();
});
}
My problem with this above code is, it's using the GetAwaiter which makes the async method synchronous. However the above implementation is super fast. It seems to manage system resources more efficiently too.
On the otherhand I have this:
private void ParallelForWithAsync()
{
Parallel.For(0, 100000, async i =>
{
await CallSendAsync(i);
});
}
This code has an async/await. However it becomes very slow, performance degrades significantly. it opens a ton of outbound ports, and eventually the HTTP requests errors out.
Thirdly I also tried this:
private void TaskWaitAll()
{
IEnumerable<int> arr = Enumerable.Range(1, 100000);
Task.WhenAll(arr.Select(CallSendAsync)).GetAwaiter().GetResult();
}
Which also had similar results as the 2nd snippet.
I .net core app where i need to call an async method to process a large number of objects. we have done this withing a Parallel.ForEach so we can make use of parallelism to complete the jobs faster.
Let me stop you right there. You don't "use parallel" to "make things faster". Parallelism is one form of concurrency (doing more than one thing at a time), and it is a form of concurrency that uses multiple threads to process CPU-bound algorithms more quickly on a multi-core machine. However, your operation is not CPU-bound at all; it is I/O-bound, which is an indicator that Parallel is the wrong technology to use for this.
If you want to process multiple items concurrently when your processing is I/O-based, the appropriate solution is to use Task.WhenAll.
however it becomes very slow, performance degrades significantly. it opens a ton of outbound ports, and eventually the HTTP requests errors out.
Yes. That's to be expected if you actually issue one hundred thousand simultaneous HTTP requests. Bear in mind there are less than 16k IANA ephemeral ports. For a massive number of requests like that, you'll probably want to limit it to a much more reasonable number - say, 20 at a time. Parallel.For will properly partition synchronous workloads based on CPU usage, number of threads in the thread pool, etc. To throttle asynchronous work, you can use a SemaphoreSlim:
private async Task TaskWaitAll()
{
var mutex = new SemaphoreSlim(20);
IEnumerable<int> arr = Enumerable.Range(1, 100000);
var tasks = arr.Select(async i =>
{
await mutex.WaitAsync();
try { await CallSendAsync(i); }
finally { mutex.Release(); }
}).ToList();
await Task.WhenAll(tasks);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Using Winforms, C#, FW 4.5.
I have a simple form with a textbox and a gridView.
When I start a new task, it's able to access the cells of the grid and change the text. When I try to change the textbox text i get this error "cross thread operation not valid..."
Both the textbox and the gridView are on the same form. Why the behavior is different?
It is generally a bad idea to access your UI from a different thread than the one which started the UI. It is possible to avoid the exception by setting the static property Control.CheckForIllegalCrossThreadCalls to false, but that is a very dangerous way.
You should rather use Control.BeginInvoke to defer execution back to the UI thread.
So you could replace your line txtSql.Text = sQuery to something like that:
void RunChecks()
{
...
SetQueryText(sQuery); // instead of txtSql.Text = sQuery;
...
}
delegate void SetTextDelegate(string text);
void SetQueryText(string query)
{
if (txtSql.InvokeRequired)
{
txtSql.BeginInvoke(new SetTextDelegate(SetQueryText), query);
return;
}
txtSql.Text = query;
}
So SetQueryText checks if it is necessary to call Invoke (or BeginInvoke) because it was called from another thread. If this is the case, it calls BeginInvoke to defer execution to the UI thread and returns.
Unfortunatly this still uses the delegate syntax instead of lambdas, but maybe there's a better syntax that I just don't know.
You need to do this for all controls you are accessing from different threads.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm almost completely virgin in threading / backgroundworkers etc.
I am trying to do this:
New window shows status of a process (label) and has an ongoing
XAML-defined animation with a storyboard (three points representing
a process in the background).
Run some background intensive code, that requires some input and
returns no output.
When finished, update the UI with a message
Repeat 2 & 3 tens of times with different operations in the background each time.
While the background BL is operating I'd like the UI not to hang, but the continuation of the execution of the next BL method should only execute after the first one has ended and the UI has been updated with the message I'd like to present.
I'd like the slimmest, simplest way to do this. using .Net 4.5, so I believe we're talking Tasks, right?
I've read dozens of Stackoverflow articles and consulted uncle google and aunt MSDN, but it's overwhelming - there are many ways to do this, and I'm a bit lost.
Thanks in advance.
Whatever you're talking about are fairly simple to do with async/await. Since you said you're new to multithreading, I recommend you to read and make yourself familiarize with it. Here is a good start and this
I assume you can implement #1 yourself and you only need guidance in implementing rest. So, I'll not be talking about it in my post.
Theoretically you need a collection with the list of work needs to be done, then start one by one after the previous one is completed.
To give some code sample
List<WorkItem> workItems = ...;//Populate it somehow
private async Task DoWorkMain()
{
foreach (var item in workItems)
{
await DoWork(item);
//WorkItem completed, Update the UI here,
//Code here runs in UI thread given that you called the method from UI
}
}
private Task DoWork(WorkItem item)
{
//Implement your logic non blocking
}
Then somewhere from the UI call
await DoWorkMain();
WorkItem is a class which holds data about the work to be done.
You need to create a thread for processing the data in the background. You can go with parameterised threads and if you want to continue the second execution only after the first is completed, set a boolean variable in the while lop of the thread or write thread synchronization.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
What is the Mutex and semaphore in C#? Where we need to implement?
How can we work with them in multithreading?
You should start at MSDN.
System.Threading.Mutex: A synchronization primitive that can also be used for interprocess synchronization.
System.Threading.Semaphore: Limits the number of threads that can access a resource or pool of resources concurrently.
Generally you only use a Mutex across processes, e.g. if you have a resource that multiple applications must share, or if you want to build a single-instanced app (i.e. only allow 1 copy to be running at one time).
A semaphore allows you to limit access to a specific number of simultaneous threads, so that you could have, for example, a maximum of two threads executing a specific code path at a time.
I'd start by reading this: http://www.albahari.com/threading/part2.aspx#_Synchronization_Essentials
and then bolster it with the MSDN links bobbymcr posted.
You might want to check out the lock statement. It can handle the vast majority of thread synchonization tasks in C#
class Test {
private static object Lock = new object();
public function Synchronized()
{
lock(Lock)
{
// Only one thread at a time is able to enter this section
}
}
}
The lock statement is implemented by calling Monitor.Enter and Monitor.Exit. It is equivalent to the following code:
Monitor.Enter(Lock);
try
{
// Only one thread at a time is able to enter this section
}
finally
{
Monitor.Exit(Lock);
}