Async question
-
- Posts: 142
- Joined: Mon Jul 25, 2016 3:58 pm
- Location: Italy
Async question
If it is not a GUI thread. Then the .Result call should work. The Result call blocks the execution until the result is available. You have to be carefull, because depending on your thread it can result to an deadlock.
Another possibility would be "Task.Run( () => asyncMethod()).Wait();"
async/await is a great thing, but everything with parallel execution requires a lot of attention and sometimes it is really hard to understand
https://learn.microsoft.com/en-us/dotne ... rom-a-task
https://stackoverflow.com/questions/172 ... -deadlocks
Another possibility would be "Task.Run( () => asyncMethod()).Wait();"
async/await is a great thing, but everything with parallel execution requires a lot of attention and sometimes it is really hard to understand
https://learn.microsoft.com/en-us/dotne ... rom-a-task
https://stackoverflow.com/questions/172 ... -deadlocks
Async question
Wolfgang,
If you want the main thread to wait until the asynchronous code finishes, then you are making things sychronous and your app will "halt" while the background code is running.
The whole idea about asynchronous is that the main thread will NOT wait and will be free for the user.
Robert
If you want the main thread to wait until the asynchronous code finishes, then you are making things sychronous and your app will "halt" while the background code is running.
The whole idea about asynchronous is that the main thread will NOT wait and will be free for the user.
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
Async question
Hi Robert,
my main problem is that in the async version of the class all calls are async, even the one I don't like to have async, like connect, change directory, directory listing, current directory and so forth. I would like to have async only the transfer methods (upload and download).
Wolfgang
my main problem is that in the async version of the class all calls are async, even the one I don't like to have async, like connect, change directory, directory listing, current directory and so forth. I would like to have async only the transfer methods (upload and download).
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
-
- Posts: 142
- Joined: Mon Jul 25, 2016 3:58 pm
- Location: Italy
Async question
Maybe you should read this.
https://learn.microsoft.com/en-us/dotne ... -scenarios
https://learn.microsoft.com/en-us/dotne ... -scenarios
Async question
Wolfgang,
Inside Visual Studio we sometimes have the same problem.
In those cases we use a helper method from the ThreadHelpers JoinableTaskFactory.
That looks like this:
I think you can do something similar with the Task.Run method.
Robert
Inside Visual Studio we sometimes have the same problem.
In those cases we use a helper method from the ThreadHelpers JoinableTaskFactory.
That looks like this:
Code: Select all
ThreadHelper.JoinableTaskFactory.Run(async delegate
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
using (new AutomationScope(this.project.Site))
{
project.SetEditLabel(value);
}
});
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
Async question
Hi Hansjörg,
thank you very much, this lik is also helpful to understand the concept better:
https://blog.stephencleary.com/2012/02/ ... await.html
Wolfgang
thank you very much, this lik is also helpful to understand the concept better:
https://blog.stephencleary.com/2012/02/ ... await.html
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Async question
Hi Robert,
I will look into it and then post the code here (if I am able to make it work).
Thank you very much!
Wolfgang
I will look into it and then post the code here (if I am able to make it work).
Thank you very much!
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Async question
Hi all,
here is a good description of asynchronos programming:
https://learn.microsoft.com/en-us/dotne ... ogramming/
Stefan
here is a good description of asynchronos programming:
https://learn.microsoft.com/en-us/dotne ... ogramming/
Stefan
Async question
Hi,
I have something very strange. Please see this code:
and the called code is
The really strange thing is the sequence:
This means that first the rest of the method is executed before the task is started!
I'm now searching a possibility to make my method wait and let the task run in the background.
Wolfgang
P.S. even this call does not resolves:
I have something very strange. Please see this code:
Code: Select all
oStopwatch := System.Diagnostics.Stopwatch{}
oStopwatch:Start()
Task.Run( { => self:_ConnectA( cHostName, cUserName, cPassword, nPort, oConfig ) } )
while _lWorking
System.Threading.Thread.Sleep( 10 )
if oStopwatch:Elapsed:Seconds > _nTimeout
_cErrorMessage := "Timeout " + _nTimeout:ToString()
exit
endif
end
_DebOut( "Waited " + oStopwatch:Elapsed:ToString() )
Code: Select all
_DebOut( "Creating AsyncFtpClient" )
_oClient := AsyncFtpClient{ cHostName, cUserName, cPassword, nPort, oConfig }
_DebOut( "Creating Task Connect()" )
oTask := _oClient:Connect()
_DebOut( "Awaiting Task Connect()" )
await oTask
_DebOut( "Task Connect() finished" )
Code: Select all
Waited 00:00:00.0029780
Client is null
Creating AsyncFtpClient
Creating Task Connect()
Awaiting Task Connect()
Task Connect() finished
I'm now searching a possibility to make my method wait and let the task run in the background.
Wolfgang
P.S. even this call does not resolves:
Code: Select all
Task.WhenAll( self:_ConnectA( cHostName, cUserName, cPassword, nPort, oConfig ) )
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
-
- Posts: 248
- Joined: Fri Oct 14, 2016 7:09 am
Async question
Hi Wolfgang,
What Robert said - you need to un-async your async
The following class will do what you want.
Then call it like this...
AsyncHelpers.RunSync(() => this.MyMethodAsync());
Apologies for the C# and the semi-colons! This is not my code originally (StackOverFlow I think), but it works perfectly.
Nick
What Robert said - you need to un-async your async
The following class will do what you want.
Code: Select all
public static class AsyncHelpers
{
/// <summary>
/// Executes an async Task<T> method which has a void return value synchronously
/// </summary>
/// <param name="task">Task<T> method to execute</param>
public static void RunSync(Func<Task> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
synch.Post(async _ =>
{
try
{
await task();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
}
/// <summary>
/// Executes an async Task<T> method which has a T return type synchronously
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="task">Task<T> method to execute</param>
/// <returns></returns>
public static T RunSync<T>(Func<Task<T>> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
T ret = default(T);
synch.Post(async _ =>
{
try
{
ret = await task();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
return ret;
}
private class ExclusiveSynchronizationContext : SynchronizationContext
{
private bool done;
public Exception InnerException { get; set; }
readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false);
readonly Queue<Tuple<SendOrPostCallback, object>> items =
new Queue<Tuple<SendOrPostCallback, object>>();
public override void Send(SendOrPostCallback d, object state)
{
throw new NotSupportedException("We cannot send to our same thread");
}
public override void Post(SendOrPostCallback d, object state)
{
lock (items)
{
items.Enqueue(Tuple.Create(d, state));
}
workItemsWaiting.Set();
}
public void EndMessageLoop()
{
Post(_ => done = true, null);
}
public void BeginMessageLoop()
{
while (!done)
{
Tuple<SendOrPostCallback, object> task = null;
lock (items)
{
if (items.Count > 0)
{
task = items.Dequeue();
}
}
if (task != null)
{
task.Item1(task.Item2);
if (InnerException != null) // the method threw an exeption
{
throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException);
}
}
else
{
workItemsWaiting.WaitOne();
}
}
}
public override SynchronizationContext CreateCopy()
{
return this;
}
}
}
AsyncHelpers.RunSync(() => this.MyMethodAsync());
Apologies for the C# and the semi-colons! This is not my code originally (StackOverFlow I think), but it works perfectly.
Nick