How to invoke async operation as sync? - events

I have a third party service which have async DoAsync() operation and Done() event. How can I create my own sync DoSync() operation?
I want smth like this (in pseudocode):
operation DoSync()
{
DoAsync();
wait until Done();
}

Try the AutoResetEvent http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx

One way to do this is to temporarily add an event handler, and in that handler, set some sort of waitable object. Here's an example that shows the technique with one of the async methods provided by WebClient
using System;
using System.Net;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
WebClient w = new WebClient();
using (var waiter = new ManualResetEventSlim())
{
DownloadDataCompletedEventHandler h = (sender, e) =>
{
if (e.Error != null)
{
Console.WriteLine(e.Error);
}
waiter.Set();
};
w.DownloadDataCompleted += h;
try
{
w.DownloadDataAsync(new Uri("http://www.interact-sw.co.uk/iangblog/"));
Console.WriteLine("Downloading");
waiter.Wait();
Console.WriteLine("Finished!");
}
finally
{
w.DownloadDataCompleted -= h;
}
}
}
}
}
Here's a simplified version that makes the basic technique easier to see, but which doesn't bother with things like error handling, or tidying up after itself:
WebClient w = new WebClient();
using (var waiter = new ManualResetEventSlim())
{
w.DownloadDataCompleted += delegate { waiter.Set(); };
w.DownloadDataAsync(new Uri("http://www.interact-sw.co.uk/iangblog/"));
Console.WriteLine("Downloading");
waiter.Wait();
Console.WriteLine("Finished!");
}
In most situations you will want to make sure you detect errors, and detach the handler when you're done - I just provided the shorter version to help illustrate the point. I wouldn't actually use that simplified one in a real program.

Related

Proper way to wait all tasks while still updating the UI thread

I'm trying to download the page source from multiple urls using tasks to download multiple sites at one time. The issue is that I want to keep the UI updated as each individual task completes. When I try to wait all tasks it stops updating the UI until they all finish. Here is the current code that I am using.
EDIT: I'm assuming I was down voted due to me not explaining well enough. I guess a better way to put this is why is the continueWith not being run before Task.WaitAll. I want the UI to update on each completion of the source being downloaded. Once that is all finished then the listbox would be updated to let the user know everything is done.
private void btnGetPages_Click(object sender, EventArgs e)
{
for (int i = 1; i < 11; i++)
{
string url = $"http://someURL/page-{i}.html";
listBoxStatus.Items.Add($"Downloading source from {url}...");
Task t = new Task(() =>
{
DownloadSource(url);
});
t.ContinueWith(prevTask => listBoxStatus.Items.Add($"Finished Downloading {url} source..."), TaskScheduler.FromCurrentSynchronizationContext());
tasks.Add(t);
t.Start();
}
Task.WaitAll(tasks.ToArray());
listBoxStatus.Items.Add("All Source files have completed...");
}
private void DownloadSource(string url)
{
var web = new HtmlWeb();
var doc = web.Load(url);
pageSource += doc.Text;
}
You really should use an asynchronous download method based on HttpClient instead of the synchronous method you are showing. Lacking that, I'll use this one:
private async Task DownloadSourceAsync(string url)
{
await Task.Run(() => DownloadSource(url));
listBoxStatus.Items.Add($"Finished Downloading {url} source...");
}
Then, you can make your btnGetPages_Click method something like this:
private async void btnGetPages_Click(object sender, EventArgs e)
{
var tasks = new List<Task>();
for (int i = 1; i < 11; i++)
{
string url = $"http://someURL/page-{i}.html";
listBoxStatus.Items.Add($"Downloading source from {url}...");
tasks.Add(DownloadSourceAsync(url));
}
Task.WaitAll(tasks.ToArray());
listBoxStatus.Items.Add("All Source files have completed...");
}

Moving comparisons out from the Update method: using delegates instead or another approach?

Let's go straight to an example. Let's say we have:
Update(){
if (value.Equals("circular")) moveGameObjectInACircularWay();
else if (value.Equals("linear")) moveGameObjectInALinearWay();
}
I think that is not very elegant solution. Unity needs to perform a comparison every frame. That does not sound very optimal to me. I'm just guessing it should be some other way to implement the same like:
Start () {
if (value.Equals("circular")) movement += moveGameObjectInACircularWay;
else if (value.Equals("linear")) movement += moveGameObjectInALinearWay;
}
Update () {
movement();
}
I guess the solution is related with delegates. That's why my proposed solution looks like delegates. I don't understand what delegates are well yet.
From MSDN "A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object." (https://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx) In short is a pointer to a method. What you want to do is the following:
using UnityEngine;
using System.Collections;
public delegate void MovementDelegate();
public class Movement : MonoBehaviour {
MovementDelegate movementFunction=null;
public string value = "linear";
void Start () {
if (value.Equals("circular")) movementFunction = moveGameObjectInACircularWay;
else if (value.Equals("linear")) movementFunction = moveGameObjectInALinearWay;
}
// Update is called once per frame
void Update()
{
if (movementFunction != null)
{
movementFunction();
}
}
void moveGameObjectInACircularWay()
{
Debug.Log("do circular movement here");
}
void moveGameObjectInALinearWay()
{
Debug.Log("do linear movement here");
}
}
The functions you declare must have the same signature as the delegate signature. If you want to add parameters to it, ex. an int, decalre your delegate as
public delegate void MovementDelegate(int speed);
and your implementation functions as
void moveGameObjectInACircularWay(int speed)
void moveGameObjectInALinearWay(int speed)
and change the call to
movementFunction(yourIntHere)
UPDATED!: Thanks to Joe Blow suggestion here is another solution:
public class Movement : MonoBehaviour
{
Action<int> movementFunction = null;
public string value = "linear";
void Start()
{
if (value.Equals("circular")) movementFunction = moveGameObjectInACircularWay;
else if (value.Equals("linear")) movementFunction = moveGameObjectInALinearWay;
}
// Update is called once per frame
void Update()
{
if (movementFunction != null)
{
movementFunction(2);
}
}
void moveGameObjectInACircularWay(int speed)
{
Debug.Log("do circular movement here "+ speed);
}
void moveGameObjectInALinearWay(int speed)
{
Debug.Log("do linear movement here " + speed);
}
}
My favorite answer has been written by Joe Blow in the comments:
Unity is components based. We better switch to Component-Based Thinking instead working with delegates.
So make two (or more) different scripts, and put those on the game object in question. Then, turn on and off these components as you wish.
So we would have to scripts added to our game object: MoveGameObjectInACircularWay.cs and MoveGameObjectInALinearWay.cs. Then a MainGameObjectScript.cs also added to our game object with the following code:
void Start () {
GetComponent()<MoveGameObjectInACircularWay>.active = true;
GetComponent()<MoveGameObjectInALinearWay>.active = false;
}

Console.ReadLine() passed to C# event

I'm learning RX and would like to use Console.ReadLine as a source for observable sequences.
I know that I can create "IEnumerable" using "yield return", but for my concrete use case I've decided to create a C# event, so that potentially many observers will be able to share the same keyboard input.
Here is my code:
class Program
{
private delegate void OnNewInputLineHandler(string line);
private static event OnNewInputLineHandler OnNewInputLineEvent = _ => {};
static void Main(string[] args)
{
Task.Run((Action) GetInput);
var input = ConsoleInput();
input.Subscribe(s=>Console.WriteLine("1: " + s));
Thread.Sleep(30000);
}
private static void GetInput()
{
while (true)
OnNewInputLineEvent(Console.ReadLine());
}
private static IObservable<string> ConsoleInput()
{
return Observable.Create<string>(
(IObserver<string> observer) =>
{
OnNewInputLineHandler h = observer.OnNext;
OnNewInputLineEvent += h;
return Disposable.Create(() => { OnNewInputLineEvent -= h; });
});
}
}
My problem - when I run the GetInput method as it is shown above, the very first input line is not sent to the sequence (but it is sent to the event handler).
However, if I replace it with the following version, everything works as expected:
private static void GetInput()
{
while (true)
{
var s = Console.ReadLine();
OnNewInputLineEvent(s);
}
}
Could someone shed some light on why this might happen?
You're trying to make life difficult for yourself. There is almost always a way to make things simple with Rx. It's just a matter of learning to think more functionally rather than procedurally.
This is all you need:
class Program
{
static void Main(string[] args)
{
var subscription = ConsoleInput().Subscribe(s => Console.WriteLine("1: " + s));
Thread.Sleep(30000);
subscription.Dispose();
}
private static IObservable<string> ConsoleInput()
{
return
Observable
.FromAsync(() => Console.In.ReadLineAsync())
.Repeat()
.Publish()
.RefCount()
.SubscribeOn(Scheduler.Default);
}
}
This lets multiple subscribers share the one input through the .Publish().RefCount(). And the .SubscribeOn(Scheduler.Default) pushes the subscription out to a new thread - without it you block on a subscription.
If you move Task.Run((Action) GetInput); to after the subscription your code will work as desired. This is because in your original version, the first call of OnNewInputEvent(Console.ReadLine()) is run before you've hooked OnNewInputLineEvent to the observer.OnNext.

how to implement async method using Task Parallel Library for I/O operations

I found that for expensive IO bound operation I can use TaskCompletionSource
as shown here http://msdn.microsoft.com/en-us/library/hh873177.aspx#workloads
But the example shown is only waiting for some time and return DateTime.
public static Task<DateTimeOffset> Delay(int millisecondsTimeout)
{
TaskCompletionSource<DateTimeOffset> tcs = null;
Timer timer = null;
timer = new Timer(delegate
{
timer.Dispose();
tcs.TrySetResult(DateTimeOffset.UtcNow);
}, null, Timeout.Infinite, Timeout.Infinite);
tcs = new TaskCompletionSource<DateTimeOffset>(timer);
timer.Change(millisecondsTimeout, Timeout.Infinite);
return tcs.Task;
}
Above code waits for timeout. I have a database call which I want to fire in the above way, but little confused in how to write it:
using (var context = new srdb_sr2_context())
{
return context.GetData("100", "a2acfid");
}
I wrote the function as below, but not sure if this is correct way of doing it:
TaskCompletionSource<IList<InstructorsOut>> tcs = null;
Timer timer = null;
timer = new Timer(delegate
{
timer.Dispose();
//prepare for expensive data call
using (var context = new srdb_sr2_context())
{
var output = context.GetData("100", "a2acfid");
//set the result
tcs.TrySetResult(output);
}
}, null, Timeout.Infinite, Timeout.Infinite);
tcs = new TaskCompletionSource<IList<InstructorsOut>>(timer);
timer.Change(0, Timeout.Infinite);
return tcs.Task;
Any help would be appreciated.
Your code doesn't make much sense to me. Timer is useful if you want to execute the code after some time, but that's not what you need here.
If you want to execute an operation on a background thread, you can use Task.Run():
Task<IList<InstructorsOut>> GetDataBackground()
{
return Task.Run(() =>
{
using (var context = new srdb_sr2_context())
{
return context.GetData("100", "a2acfid");
}
});
}
Using a background thread this way can be useful in UI apps, where you don't want to block the UI thread. But if you have something like ASP.NET application, this won't actually give you any performance or scalability improvements. For that, the GetData() method would have to be made truly asynchronous.

C# like events in D programming language

I recently finished a 6-month internship at a company that uses C# for the most part of their programming. During this time I first used and got accustomed to the C# way of doing events. Like shown below:
acc.AccountBalanceLow += new AccountBalanceDelegate(atm.AccountToLow);
acc.AccountBalanceLow +=new AccountBalanceDelegate(atm.AccountToLowAgain);
Does D support such constructs? I'd imagine one could be created by the user by using operator overloading, but I'm not entirely sure. If it's not possible what would then be a common excepted way of doing it then?
The equivalent construct in D is to use Signals and Slots. This is a different means of implementing the Observer Pattern, which is effectively what a C# event does.
D (and C++) use an analogous pattern called signals and slots.
If you're feeling the need to use the C# style-events instead of signals and slots, they're extremely simple to implement:
module fluidity.core.event;
class Event {
alias void delegate(EventArgs) handler_t;
handler_t[] handlers;
Object owner;
this() {}
this(Object o) { owner = o; }
void attach(handler_t handler) {
if (handler)
handlers ~= handler;
}
void detach(handler_t handler) {
int i = -1;
foreach (j, h; handlers)
{
if (h is handler)
{
i = j;
break;
}
}
if (i > -1)
handlers = handlers[0..i] ~ handlers[i+1..$];
}
void raise() { raise(new EventArgs(owner)); }
void raise(EventArgs e) {
// call all handlers
foreach (handler; handlers)
{
if (handler)
handler(e);
}
}
void opAddAssign(handler_t handler) {
attach(handler);
}
void opSubAssign(handler_t handler) {
detach(handler);
}
}
class EventArgs {
Object source;
bool handled;
void handle() { handled = true; }
this() {}
this(Object s) {
source = s;
}
}
Here is an example of c# style events using signals, slots, and a templates:
events.d:
import std.signals;
class Event(T...){
mixin Signal!(T);
void broadcast(T args){
emit(args);
}
void opAddAssign(slot_t slot){
connect(slot);
}
void opSubAssign(slot_t slot) {
disconnect(slot);
}
}
declaration:
public Event!(int) onSomeEventOfInt;
public Event!(string, int) onSomeEventOfStringAndInt;
instantiation:
this.onSomeEventOfInt = new Event!(int)();
this.onSomeEventOfStringAndInt = new Event!(string, int)();
fire event:
int i = 4;
string str = "hello";
this.onSomeEventOfInt.broadcast(i);
this.onSomeEventOfStringAndInt.broadcast(str, 4);
observer registration:
obj1.onSomeEventOfInt += &handleEventOfInt
obj1.onSomeEventOfStringAndInt += &handleEventOfStringAndInt
void handleEventOfInt(int g)
{ /*do something */ }
void handleEventOfStringAndInt(string str, int g)
{ /*do something */ }
Check out DFL's event system. It works EXACTLY the same way as C# .NET.
DFL Event Example
Download DFL, grab the events module and use it the way you like. I modified it to use variadic template arguments. This gives maximum flexibility.
http://www.dprogramming.com/dfl098.zip

Resources