I am stuck at correctly disposing Threads, created with RX, on application exiting. I see in Process Explorer that after application closed, threads are still running, causing an IO exceptions.
class Program
{
static void Main(string[] args)
{
CompositeDisposable subsriptions = new CompositeDisposable();
subscriptions.Add(Observable.Interval(TimeSpan.FromSeconds(15))
.Subscribe(_ =>
{
getData();
}));
Thread.Sleep(TimeSpan.FromSeconds(20));
subscriptions.Dispose();
}
}
}
If you see if I uncomment the subscription.Dispose(), the thread terminates without getting any data. Any help would be appreciated. Thanks
You need some sort of delay between subsriptions.Add(...) and subscriptions.Dispose(). Without a delay between there, your app is simply subscribing and disposing them immediately, with no time for the threads to do their work. (And the Thread.Sleep(1000) doesn't work, since it is inside the subscription function, not part of the main function.)
The pattern you are looking for is similar to this
class Program {
public string GetData(){
return "Hello";
}
public string async GetDataAsync(){
return await Observable
.Interval(TimeSpan.FromSeconds(15))
.Take(1)
.Select(()=>GetData());
}
static void Main(string[]args){
var s = GetDataAsync().Wait();
}
}
The reason for Wait is that an entry point, Main, in this case cannot be
marked as async. Wait blocks the current thread until the Task returned
by GetDataAsync produces a value.
Note also that IObservable is compatible with async/await and will return the last
value produced by the sequence. That is why I add Take(1) as it will produce
only 1 tick.
Another alternative is just to call Wait directly on the IObservable as in
class Program {
public string GetData(){
return "Hello";
}
public IObservable<string> GetDataObservable(){
return Observable
.Interval(TimeSpan.FromSeconds(15))
.Take(1)
.Select(()=>GetData());
}
static void Main(string[]args){
var s = GetDataObservable().Wait();
}
}
You can subscribe your observable with the CancellationToken that will cancel the underlying task execution:
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Observable.
Interval(TimeSpan.FromSeconds(15)).
Subscribe(_ => getData(), cts.Token));
cts.CancelAfter(TimeSpan.FromSeconds(20));
}
Related
I'm trying to find out how to use WhenAll to let two methods run at once, and once they both finish, collect the results without blocking by using .Result
I have this little console app test:
using System.Diagnostics;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
public static void Main(string[] args)
{
var run = TaskRunner();
Debug.WriteLine(run);
if (run.IsCompleted)
{
Debug.WriteLine("this worked!");
} else
{
Debug.WriteLine("this failed!");
}
}
public static async Task<string> TaskRunner()
{
var taskOne = OneAsync();
var taskTwo = TwoAsync();
var tasks = await Task.WhenAll(taskOne, taskTwo);
var retval = tasks[0] + tasks[1];
return retval;
}
public static Task<string> OneAsync()
{
return Task.Run(() =>
{
return "test1";
});
}
public static Task<string> TwoAsync()
{
return Task.Run(() =>
{
return "test2";
});
}
}
}
This currently prints this worked! to my Output window... However, if I comment out Debug.WriteLine(run); it prints this failed!... Why does the Task complete simply by being logged to the output window?
I'm trying to understand a huge problem in a complex piece of code and this little test is my MCVE to hopefully shed some light on what is happening behind the scenes.
This happens just by pure chance. The way you are starting your task is with Task.Run. This essentially creates a new thread on which the (synchronous) action is executed. It returns a task for the completion of that thread.
So OneAsync and TwoAsync will each spawn a new thread that then immediately returns a string. This will happen very quickly but there’s still some overhead for creating those threads which means that it won’t be instantaneous.
TaskRunner then calls both those methods (spawning the threads), and then asynchronously waits for both threads to finish. Since the threads are not completely instantly, this TaskRunner method also won’t complete instantly.
Now, in your main, you are starting the asynchronous TaskRunner, which we figured will take “a very short moment”. You do not await the task, so the execution continues immediately. Debug.WriteLine is executed to print something (it probably doesn’t really matter that it’s the task in question that is being printed), and then you are checking the state of the task.
Since printing stuff is relatively slow (compared to other operations), this is probably the reason why the tasks ends up being completed. And when you remove the printing, the if is just reached too quickly for the task to finish.
As you likely noticed, working like that with asynchronous tasks does not appear to be a good idea. That’s why you should always await the task when you depend on its result.
// note the *async* here; async main methods are supported with C# 7.1
public static async void Main(string[] args)
{
var run = TaskRunner();
// await the task
await run;
if (run.IsCompleted)
{
Debug.WriteLine("this worked!");
}
else
{
Debug.WriteLine("this failed!");
}
}
I am rather new to task based programming and trying to determine how to return a task and verify that it has been started. The code that I got to work was not what I was expecting. The console application is as follows:
public static void Main(string[] args)
{
var mySimple = new Simple();
var cts = new CancellationTokenSource();
var task = mySimple.RunSomethingAsync(cts.Token);
while (task.Status != TaskStatus.RanToCompletion)
{
Console.WriteLine("Starting...");
Thread.Sleep(100);
}
Console.WriteLine("It is started");
Console.ReadKey();
cts.Cancel();
}
public class Simple
{
public async void RunSomething(CancellationToken token)
{
var count = 0;
while (true)
{
if (token.IsCancellationRequested)
{
break;
}
Console.WriteLine(count++);
await Task.Delay(TimeSpan.FromMilliseconds(1000), token).ContinueWith(task => { });
}
}
public Task RunSomethingAsync(CancellationToken token)
{
return Task.Run(() => this.RunSomething(token));
}
}
The output is:
Starting...
0
It is started
1
2
3
4
Why is the task that is being returned have a status as TaskStatus.RanToCompletion compared to TaskStatus.Running as we see that the while loop is still executing? Am I checking the status of the task of putting the RunSomething task on the threadpool rather than the RunSomething task itself?
RunSomething is an async void method, meaning it exposes no means of the caller ever determining when it finishes, they can only ever start the operation and then have no idea what happens next. You then wrap a call to it inside of Task.Run, this is schedluing a thread pool thread to start RunSomething. It will then complete as soon as it has finished starting that Task.
If RunSomething actually returned a Task, then the caller would be able to determine when it actually finished, and if you waited on it it wouldn't actually indicate that it was done until that asynchronous operation was actually finished (there would be no reason to use Task.Run to start it in another thead, you'd be better off just calling it directly and not wasting the effort of moving that to a thread pool thread).
Never use async void (https://msdn.microsoft.com/en-us/magazine/jj991977.aspx)
instead you should use async Task
If you need to call an async method from a non-async (such as from a static void main) you should do something like this:
mySimple.RunSomethingAsync(cts.Token).GetAwaiter().GetResult();
That will effectively make the method a synchronous call.
You can use async void, but only for events.
So I'm still trying to understand the async/await pattern, but I'm also trying to achieve the following behavior:
A method A calls method B which runs a number of processes. Some of those processes can be run on separate threads while other things are being processed so that their return values will be available closer to when they are needed. Method B needs to not return control to the caller until all of these processes are completed.
Here is the test code that I am working with:
static void Main(string[] args)
{
CallProc();
Console.WriteLine("Program finished");
Console.ReadKey();
}
public static async Task CallProc()
{
var two = Task.Factory.StartNew(() => SomeSynchronousProcessIDontOwn(5000, "two"));
var one = Task.Factory.StartNew(() => SomeSynchronousProcessIDontOwn(500, "one"));
var three = Task.Factory.StartNew(() => SomeSynchronousProcessIDontOwn(1500, "three"));
// some process happens here
var oneMessage = await one; // waits until one finishes and then snags it's value
Console.WriteLine("Got message {0}", oneMessage);
// some more stuff happens here
var twoMessage = await two; // waits until two is finished and then snags it's value
Console.WriteLine(twoMessage);
// TODO: need to make sure that everything is completed before returning control to caller
}
public static string SomeSynchronousProcessIDontOwn(int delayTime, string message, bool delay = true)
{
Console.WriteLine("Starting \"{0}\"", message);
if(delay) Thread.Sleep(delayTime);
return string.Format("Finished \"{0}\"", message);
}
Right now, what is happening is that everything words as I expected except that the method is returning before everything is finished, so the output shows "Program finished" while "two" is still running.
How do I write this so that CallProc() can execute those tasks asynchronously but delay returning until everything has been completed. In other words, CallProc() needs to run some tasks asynchronously, but CallProc() itself needs to be called synchronously.
The idea of an asynchronous method, which is what you've written is that it will return control (approximately) immediately and the task that it returns will be marked as completed when the operation that it conceptually represents finishes.
This means that your program should either be looking at the resulting task to see when it finishes, or that you don't want an asynchronous method in the first place, and you should re-write CallProc synchronously rather than asynchronously.
To make CallProc synchronous simply remove async (and adjust the return type accordingly), and wait on each task instead of using await.
If CallProc really should be asynchronous then the caller should be adding a continuation (or using await) to perform an action when the task is completed, rather than when the method returns.
Instead of awaiting each task individually why not just await all of them using WhenAll
public static async Task CallProc()
{
var two = Task.Factory.StartNew(() => SomeSynchronousProcessIDontOwn(5000, "two"));
var one = Task.Factory.StartNew(() => SomeSynchronousProcessIDontOwn(500, "one"));
var three = Task.Factory.StartNew(() => SomeSynchronousProcessIDontOwn(1500, "three"));
// run synchronous tasks
await Task.WhenAll(one, two, three);
}
If you would prefer to have CallProc block (i.e. not return until all tasks have finished) then remove the async declaration and use Task.WaitAll instead.
public static void CallProc()
{
// start tasks
Task.WaitAll(one, two, three);
}
One way to do this is to simply call Wait() on the result of CallProc. This will essentially wait for the task returned by CallProc to finish before it continues. Calling Wait in a GUI app can cause a deadlock but for a console app it is fine.
static void Main(string[] args)
{
CallProc().Wait();
Console.WriteLine("Program finished");
Console.ReadKey();
}
That will ensure that "Program finished" is printed after task two is finished.
I'm making a windows phone game with Unity3d and I have the need to call a method from the Unity thread asynchronously from the UI thread.
This all works, however with one particular method the first execution executes as expected however after the second it seems to lock up the game.
private async static Task<String> ShowDescriptionProductListing()
{
var x = await CurrentApp.LoadListingInformationAsync();
StringBuilder builder = new StringBuilder();
builder.AppendFormat("{0}\n{1}", x.Description,
x.ProductListings.FirstOrDefault().Value);
return builder.ToString();
}
public static void ShowDescrProduct()
{
string x = ShowDescriptionProductListing().Result;
MessageBox.Show(x);
}
I think the line:
var x = await CurrentApp.LoadListingInformationAsync();
Is most likely the culprit, however I'm having a hard time debugging it.
The class which 'holds' that method in unity is like so:
public static class HelperClass
{
public static void ShowDescrProduct()
{
Dispatcherr.InvokeOnUIThread(Tests.ShowDescrProduct); //The method above
}
}
Dispatcherr (Yeah i need to use namespaces haha) just holds two Action properties that I set inside the UI thread.
public void EnterUIThread(Action action)
{
Dispatcher.BeginInvoke(() =>
{
action();
});
}
private void Unity_Loaded()
{
Dispatcherr.InvokeUIThread = EnterUIThread; //One of the actions I just
//mentioned being assigned the above
//method
}
And it's in the EnterUIThread call to Dispatcher.BeginInvoke that it seems to get locked up, only after the first call - which is always successful.
Confusing me slightly to say the least.
Anyone able to give any insight?
Thanks in advance
You're calling Result on the asynchronous operation. This is going to cause the UI thread to block until the asynchronous operation finishes. The asynchronous operation needs to wait for the UI thread to be free so that the continuation to LoadListingInformationAsync can be scheduled in the UI thread.
Both operations are waiting on each other to finish. Deadlock.
You need to not block the UI thread while waiting for this operation to finish. You should await it instead, making ShowDescrProduct and async method.
I saw in WCF they have the [OperationContract(IsOneWay = true)] attribute. But WCF seems kind of slow and heavy just to do create a nonblocking function. Ideally there would be something like static void nonblocking MethodFoo(){}, but I don't think that exists.
What is the quickest way to create a nonblocking method call in C#?
E.g.
class Foo
{
static void Main()
{
FireAway(); //No callback, just go away
Console.WriteLine("Happens immediately");
}
static void FireAway()
{
System.Threading.Thread.Sleep(5000);
Console.WriteLine("5 seconds later");
}
}
NB: Everyone reading this should think about if they actually want the method to finish. (See #2 top answer) If the method has to finish, then in some places, like an ASP.NET application, you will need to do something to block and keep the thread alive. Otherwise, this could lead to "fire-forget-but-never-actually-execute", in which case,of course, it would be simpler to write no code at all. (A good description of how this works in ASP.NET)
ThreadPool.QueueUserWorkItem(o => FireAway());
(five years later...)
Task.Run(() => FireAway());
as pointed out by luisperezphd.
For C# 4.0 and newer, it strikes me that the best answer is now given here by Ade Miller: Simplest way to do a fire and forget method in c# 4.0
Task.Factory.StartNew(() => FireAway());
Or even...
Task.Factory.StartNew(FireAway);
Or...
new Task(FireAway).Start();
Where FireAway is
public static void FireAway()
{
// Blah...
}
So by virtue of class and method name terseness this beats the
threadpool version by between six and nineteen characters depending on
the one you choose :)
ThreadPool.QueueUserWorkItem(o => FireAway());
For .NET 4.5:
Task.Run(() => FireAway());
To add to Will's answer, if this is a console application, just throw in an AutoResetEvent and a WaitHandle to prevent it exiting before the worker thread completes:
Using System;
Using System.Threading;
class Foo
{
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static void Main()
{
ThreadPoolQueueUserWorkItem(new WaitCallback(FireAway), autoEvent);
autoEvent.WaitOne(); // Will wait for thread to complete
}
static void FireAway(object stateInfo)
{
System.Threading.Thread.Sleep(5000);
Console.WriteLine("5 seconds later");
((AutoResetEvent)stateInfo).Set();
}
}
An easy way is to create and start a thread with parameterless lambda:
(new Thread(() => {
FireAway();
MessageBox.Show("FireAway Finished!");
}) {
Name = "Long Running Work Thread (FireAway Call)",
Priority = ThreadPriority.BelowNormal
}).Start();
By using this method over ThreadPool.QueueUserWorkItem you can name your new thread to make it easier for debugging. Also, don't forget to use extensive error handling in your routine because any unhandled exceptions outside of a debugger will abruptly crash your application:
The recommended way of doing this when you are using Asp.Net and .Net 4.5.2 is by using QueueBackgroundWorkItem. Here is a helper class:
public static class BackgroundTaskRunner
{
public static void FireAndForgetTask(Action action)
{
HostingEnvironment.QueueBackgroundWorkItem(cancellationToken => // .Net 4.5.2 required
{
try
{
action();
}
catch (Exception e)
{
// TODO: handle exception
}
});
}
/// <summary>
/// Using async
/// </summary>
public static void FireAndForgetTask(Func<Task> action)
{
HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => // .Net 4.5.2 required
{
try
{
await action();
}
catch (Exception e)
{
// TODO: handle exception
}
});
}
}
Usage example:
BackgroundTaskRunner.FireAndForgetTask(() =>
{
FireAway();
});
or using async:
BackgroundTaskRunner.FireAndForgetTask(async () =>
{
await FireAway();
});
This works great on Azure Web Sites.
Reference: Using QueueBackgroundWorkItem to Schedule Background Jobs from an ASP.NET Application in .NET 4.5.2
Calling beginInvoke and not catching EndInvoke is not a good approach. Answer is simple:
The reason that you should call EndInvoke is because the results of the invocation (even if there is no return value) must be cached by .NET until EndInvoke is called. For example if the invoked code throws an exception then the exception is cached in the invocation data. Until you call EndInvoke it remains in memory. After you call EndInvoke the memory can be released. For this particular case it is possible the memory will remain until the process shuts down because the data is maintained internally by the invocation code. I guess the GC might eventually collect it but I don't know how the GC would know that you have abandoned the data vs. just taking a really long time to retrieve it. I doubt it does. Hence a memory leak can occur.
More can be found on http://haacked.com/archive/2009/01/09/asynchronous-fire-and-forget-with-lambdas.aspx
Almost 10 years later:
Task.Run(FireAway);
I would add exception handling and logging inside FireAway
The simplest .NET 2.0 and later approach is using the Asynchnonous Programming Model (ie. BeginInvoke on a delegate):
static void Main(string[] args)
{
new MethodInvoker(FireAway).BeginInvoke(null, null);
Console.WriteLine("Main: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
}
private static void FireAway()
{
Thread.Sleep(2000);
Console.WriteLine("FireAway: " + Thread.CurrentThread.ManagedThreadId );
}
The simplest way to do fire-and-forget is to use the discard pattern:
_ = MyFireAndForgetTask(myParameters);
This notifies your method that the result of your Task will not be needed and execution of the thread is not stalled.
Please note that the Task must call Task.Run within it to be asynchronous using this pattern. Using our previous method as an example:
Task MyFireAndForgetTask(myParameters)
{
return Task.Run(/* put Task, Func<T>, or Action here*/);
}
If this step is ignored, the Task will run synchronously and will not behave as expected.
Furthermore the assignment pattern can be used. This is useful for when the method runs until the last line but hangs until the Task is finished. We will utilize Task.Wait() for this. Using our previous method as an example:
void MyCustomEventHandler(object sender, EventArgs args)
{
/* perform some code here */
var myTask = MyFireAndForgetTask(myParameters);
/* perform some more code here; thread is not blocked */
/// Hang the method until the Task is completed.
/// using "await myTask;" is equivalent.
myTask.Wait();
}
This will perform a fire-and-forget-till-completion, which is mandatory on some platforms (i.e. ASP.NET).
If you want to test in Console keep in mind that Console.ReadKey() or something like that is needed before Console loses its thread by Press any key to continue ...
public static void Main()
{
Task.Factory.StartNew(async () =>
{
await LongTaskAsync();
}, TaskCreationOptions.LongRunning).ConfigureAwait(false);
Console.WriteLine("Starts immediately");
Console.ReadKey();
}
static async Task LongTaskAsync()
{
await Task.Delay(5000);
Console.WriteLine("After 5 seconds delay");
}