Visual C# .net 2013 & Threads how-to - c#

I'm normally developping in java but I have now to develop a little wpf application using visual c# 2013 and ... it seems to be more complex than java.
So perhaps I will have lot of questions about it.
For the moment I'm working on threads.
And my first question is : what is the difference between that two ways for creating threads
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void Threads_Button_Click_1(object sender, RoutedEventArgs e)
{
Thread th1 = new Thread(doSomething1);
th1.Start();
Thread th2 = new Thread(new ThreadStart(doSomething2));
th2.Start();
}
private void doSomething1()
{
Console.WriteLine("Starting doSomething1");
Thread.Sleep(3000);
Console.WriteLine("Finishing doSomething1");
}
private void doSomething2()
{
Console.WriteLine("Starting doSomething2");
Thread.Sleep(6000);
Console.WriteLine("Finishing doSomething2");
}
}

They are both the same, what you see there happening is syntax sugar called Delegate Inference.
Delegate inference allows you to make a direct assignment of a method
name to a delegate variable, without wrapping it first with a delegate
object.
In simple words, the compiler sees that the doSomething1 method matches a ThreadStart Delegate so just creates one for you. It knows it should match the ThreadStart because that's in one of the constructor's parameters.
For more possibilities (with lambdas etc...) see this blog.

Storment's answer is correct, but I thought I'd chime in with an alternative way of doing what you are doing that is considered best practice: using Tasks. I am assuming that since you are using VS 2013 that you are targeting .NET 4.5 so you also have the async'/awaitkeywords available to you. With your current little example app, you are going to run into trouble if you try to update your UI fromdoSomething1()ordoSomething2()` because only the UI thread can modify UI controls and those methods are running on different threads.
I'd suggest instead doing something like this:
//notice the async keywords in the method declarations
private async void Threads_Button_Click_1(object sender, RoutedEventArgs e)
{
List<Task> tasks = new List<Task>();
tasks.Add(doSomething1());
tasks.Add(doSomething2());
//this will wait until both doSomething1() and doSomething2() are done in a non-blocking fashion
await Task.WhenAll(tasks);
}
private async Task doSomething1()
{
//you can now update UI controls here
Console.WriteLine("Starting doSomething1");
await Task.Delay(3000);
Console.WriteLine("Finishing doSomething1");
}
private async Task doSomething2()
{
//you can now update UI controls here
Console.WriteLine("Starting doSomething2");
await Task.Delay(6000);
Console.WriteLine("Finishing doSomething2");
}
This is obviously much different than what you have right now, but (other users, please correct me if you have a quibble with this statement), with "modern" .NET, you really shouldn't need to spin up your own threads in a WPF application like this. This again assumes you are targeting .NET 4.5, which, by default, VS 2013 will do (to be more pedantic, it would be 4.5.1 but that is immaterial in this context).
If you are interested in using async/await instead, I'd suggest reading up on it, perhaps by starting with the helpful FAQ on the Parallel Programming blog on MSDN and/or with Stephen Cleary's intro blog post.

Related

Does .NET 6's PeriodicTimer capture the current SynchronizationContext by default?

For PeriodicTimer (AsyncTimer at the time), regarding WaitForNextTickAsync, David Fowler mentioned "The execution context isn't captured" (here) via (here). However, given that was not necessarily the final implementation, I reviewed the PeriodicTimer documentation which makes no mention of context capturing.
Based on Stephen Toub's decade old, but still excellent, "The Task-based Asynchronous Pattern," and the following code:
private CancellationTokenSource tokenSource;
private async void start_Click(object sender, EventArgs e)
{
tokenSource = new CancellationTokenSource();
var second = TimeSpan.FromSeconds(1);
using var timer = new PeriodicTimer(second);
try
{
while (await timer.WaitForNextTickAsync(tokenSource.Token).ConfigureAwait(false))
{
if (txtMessages.InvokeRequired)
{
txtMessages.Invoke(() => txtMessages.AppendText("Invoke Required..." + Environment.NewLine));
}
else
{
txtMessages.AppendText("Invoke NOT Required!" + Environment.NewLine);
}
}
} catch (OperationCanceledException)
{
//disregard the cancellation
}
}
private void stop_Click(object sender, EventArgs e)
{
tokenSource.Cancel();
}
If ConfigureAwait is passed true (or removed entirely), my output is as follows:
Invoke NOT Required!
Invoke NOT Required!
Invoke NOT Required!
Invoke NOT Required!
...
However, if ConfigureAwait is passed false, my output is as follows:
Invoke Required...
Invoke Required...
Invoke Required...
Invoke Required...
...
Unless I'm confusing SynchronizationContext with "executing thread," it seems like the current SynchronizationContext IS captured by default. Can anyone (maybe one of the greats) please clarify?
The new (.NET 6) PeriodicTimer component is not like all other Timer components that raise events or execute callbacks. This one resembles more the Task.Delay method. It exposes a single asynchronous method, the method WaitForNextTickAsync. This method is not special in any way. It returns a standard ValueTask<bool>, not some kind of exotic awaitable like the Task.Yield method (YieldAwaitable).
When you await this task, you control the SynchronizationContext-capturing behavior of the await like you do for any other Task or ValueTask: with the ConfigureAwait method. If you know how to use the ConfigureAwait with the Task.Delay, you also know how to use it with the PeriodicTimer.WaitForNextTickAsync. There is absolutely no difference.
If you don't know what the ConfigureAwait does, or you want to refresh your memory, there is a plethora of good articles to read. For the sake of variance I'll suggest this old 5-minute video by Lucian Wischik: Tip 6: Async library methods should consider using Task.ConfigureAwait(false)

How to to avoid race conditions on the UI thread when using async/await [duplicate]

This question already has answers here:
Async lock not allowed
(2 answers)
Closed 4 years ago.
We have all heard that it's important to keep the UI thread responsive, so we implement async/await everwhere.
I'm building a text editor, where 'everything' is asynchron. However, now I find that its subject to race conditions on the UI thread when code runs before other code has finished.
Of course thats the whole idea of 'responsive UI thread', that it can run code, while it's awating other code.
I need some code to wait for other code to finish before it runs. I have boiled the problem down to this code where I simply process keystrokes:
private async void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
//Wait until it's your turn (await HandleKey has returned) before proceeding
await HandleKey(e.KeyChar);
}
async Task HandleKey(char ch)
{
await GetCaretPosition();
Point newPosition = await Task.Delay(1000);
await SetCaretPosition(newPosition);
}
As you can see when the first key is processed (awating) the next key can start to process. In this simple case the second key handling code will get an old value of caretposition,
because the first key handling has not yet updated caretposition.
How can I make the code in KeyPress event wait until the first key has finished processing?
Going back to synchron coding is not an option.
For anyone browsing this: This is what I came up with, based on k1dev's link about SemaphoreSlim (read about it here.
It's actually suprisingly easy. Based on the code in the question, I add a SemaphoreSlim and Waits on it (asynchron). A SemaphoreSlim is a lightweight Semaphore especially made for wating on the UI thread. I use a Queue<char> to make sure keys are handled in the right order:
SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
Queue<char> queue = new Queue<char>();
private async void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
queue.EnQueue(e.KeyChar);
await semaphore.WaitAsync();
try
{
await HandleKey(queue.DeQueue());
}
finally
{
semaphore.Release();
}
}
As a bonus: I have a method that I simply want to skip if the app is busy, that can be done using this code:
if (await semaphore.WaitAsync(0)) //Note the zero as timeout
{
try
{
await MyMethod();
}
finally
{
semaphore.Release();
}
}
First, it sounds like there is more to this question or that there are likely to be follow-ups.
That said, you may try to make your HandleKey synchronized to manage shared resources:
[MethodImpl(MethodImplOptions.Synchronized)]
async Task HandleKey(char ch)
{
Try this thread for reference:
C# version of java's synchronized keyword?
PS - So the more I think about this the more it seems like your trying to perform some unit of work synchronously but offload it off the ui thread. That said, synchronizing the HandleKey method won't achieve the desired result. I think you may be looking for a Dispatcher pattern:
https://www.what-could-possibly-go-wrong.com/the-dispatcher-pattern/
https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher(v=vs.110).aspx

Ignoring the return value from an async Task method

Here's the scenario: In my WPF app I'd like to keep a loop running at all times that does various things. This pattern came to mind:
void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
SomeProcessAsync(); //throw away task
}
async Task SomeProcessAsync()
{
while (true)
{
DoSomething();
await Task.Delay(1000);
}
}
The call triggers a warning since the return value is unused. What is the cleanest way to silence that warning?
#pragma warning disable 4014
AddItemsAsync(); //throw away task
#pragma warning restore 4014
This works but it looks so nasty!
Btw, I also could have used a timer but I liked the simplicity of this loop.
As already mentioned in chris' answer, the right solution here is to turn the event handler into an async void method and then use await, so that exceptions are propagated correctly.
But if you really want to ignore the Task, then you can assign it to a variable:
var ignored = SomeProcessAsync();
Or in C# 7.0, you can use discard:
_ = SomeProcessAsync();
You can make the event handler async:
async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
await SomeProcessAsync(); //throw away task
}
Normally, async void is bad, but it's necessary when an event handler is async and exceptions should be handled here instead of in whatever calls this. You can (and should) use the normal ConfigureAwait(false) if SomeProcessAsync doesn't need the UI context.
My solution is to silence the compiler warning with a little helper method that is reusable:
static class TaskHelpers
{
/// <summary>Signifies that the argument is intentionally ignored.</summary>
public static void DiscardTask(this Task ignored)
{
}
}
And the call looks like this:
AddItemsAsync().DiscardTask();
That's clean and self-documenting. Still looking for a better name for the helper.
Async-await uses threads from the thread pool. Although the number of threads in the thread pool is fairly large, and possibly adjustable, it is still a limited number of threads.
The threads in the thread pool are optimized for short living tasks. They start and finish fast, the results from these thread can be accessed fairly easily. But these advantages come with a cost. If not, all threads would be threads from the thread pool.
If you want to let your thread do something for a fairly long time, it is best to use a regular System.Threading.Thread, possibly wrapped in a System.ComponentModel.BackgroundWorker.
Better to create a task with your delegate code
Task.Factory.StartNew( () => {} );

Why using async/await to a function takes longer time then calling that same function directly?

I have a function which I need to run in background because it freezes the UI until it completes. I tried to use Async/Await which lets me use the UI no matter the function completes running or not, but I noticed it is much slower. Why using async/await to a function takes longer time then calling that same function directly ? Is there any other alternative ?
private void btnClick(object sender, EventArgs e)
{
Math4OfficeRibbon.CallFunction();
MessageBox.Show("Task Finished");
}
public async void CallFunction()
{
await Task.Run(() => AwaitedFunction());
}
public static void AwaitedFunction()
{
// Do Something
// Takes longer time this way
}
In order to find out why it's much slower you can track events down in visual studio by using Console.WriteLine($"{event name} {DateTime.Now}")
And then seeing where it takes the most time in output window.
However about the alternatives, I suggest you use BackgroundWorker to run your tasks.
note that you need to invoke controls in order to make changes to the ui through the backgroundWorker
BackgroundWorker _worker = new BackgroundWorker();
_worker.DoWork+=(o,args)=>
{
//your code here.
}
_worker.RunWorkerAsync();
You also have RunWorkerCompleted event which you can use to do things after your task is done running.
Backgroundworker also has the IsBusy property which you can use along with a while loop to keep the thread waiting for its completion without freezing the UI by doing :
While(_worker.IsBusy)
{
Application.DoEvents();
}
In order to invoke to do things on the ui thread you need to do the following within BackgroundWorker:
BeginInvoke(new Action(()=>
{
//ui action here for example:
MessageBox.show("test")
}));
However in order to find out why your asynchronous operation takes alot of time you have to trace it using the console because you have all the code and you know what you're doing.

C#/.NET 4.5 - Why does "await Task.WhenAny" never return when provided with a Task.Delay in a WPF application's UI thread?

Given the following code, why does ask.WhenAny never return when provided with a Task.Delay of 1 second? Technically I'm not sure if it does return after a extended amount of time, but it doesn't after 15 seconds or so after which I manually kill the process. According to the documentation I shouldn't be required to manually start the delayTask, and in fact I receive a exception if I try to do so manually.
The code is being called from the UI thread when a user selects a context menu item in a WPF application, although it works fine if I have the click method specified for the context menu item run this code in a new thread.
public void ContextMenuItem_Click(object sender, RoutedEventArgs e)
{
...
SomeMethod();
...
}
public void SomeMethod()
{
...
SomeOtherMethod();
....
}
public void SomeOtherMethod()
{
...
TcpClient client = Connect().Result;
...
}
//In case you're wondering about the override below, these methods are in
//different classes i've just simplified things here a bit so I'm not posting
//pages worth of code.
public override async Task<TcpClient> Connect()
{
...
Task connectTask = tcpClient.ConnectAsync(URI.Host, URI.Port);
Task delayTask = Task.Delay(1000);
if (await Task.WhenAny(connectTask, delayTask) == connectTask)
{
Console.Write("Connected\n");
...
return tcpClient;
}
Console.Write("Timed out\n");
...
return null;
}
If I change ContextMenuItem_Click to the following it works fine
public void ContextMenuItem_Click(object sender, RoutedEventArgs e)
{
...
new Thread(() => SomeMethod()).Start();
...
}
I predict that further up your call stack, you're calling Task.Wait or Task<T>.Result. This will cause a deadlock that I explain in full on my blog.
In short, what happens is that await will (by default) capture the current "context" and use that to resume its async method. In this example, the "context" is the WPF UI context.
So, when your code does its await on the task returned by WhenAll, it captures the WPF UI context. Later, when that task completes, it will attempt to resume on the UI thread. However, if the UI thread is blocked (i.e., in a call to Wait or Result), then the async method cannot continue running and will never complete the task it returned.
The proper solution is to use await instead of Wait or Result. This means your calling code will need to be async, and it will propagate through your code base. Eventually, you'll need to decide how to make your UI asynchronous, which is an art in itself. At least to start with, you'll need an async void event handler or some kind of an asynchronous MVVM command (I explore async MVVM commands in an MSDN article). From there you'll need to design a proper asynchronous UI; i.e., how your UI looks and what actions it permits when asynchronous operations are in progress.

Categories

Resources