in my Windows 8.1 universal app I want to retrieve a local XML file on application start. But I'm confused with async / await. I use GetFileAsync, so it needs to be in an async function. But I could not call it from the initialization of the app. When I just call the function it says i need to add await. If I await, it says I could use await only in an async method, and therefore I could not do it in the initialization. So how could this be done?
Many thanks!
See here: How to call asynchronous method from synchronous method in C#?
"If you have a simple asynchronous method that doesn't need to synchronize back to its context, then you can use Task.WaitAndUnwrapException"
So put the code into a separate method and use the method above or the second method RunTask.
Related
From the description in the pika documentation, I can't quite get what add_callback_threadsafe() method does. It says, "Requests a call to the given function as soon as possible in the context of this connection’s thread". Specifically, which event does this callback get associated to? Since, add_callback_threadsafe() doesn't receive any "event" argument, how does pika know when to invoke that callback?
Also, in the official example, why do we even need to build the partial function and register the callback in the do_work() method? Could we not just call the ack_message() method after the time.sleep() is over?
The reason why the method exists:
How to add multiprocessing to consumer with pika (RabbitMQ) in python
If you use the same rabbit connection/channel with multiple threads/processes then you'll be prone to crashes. If you want to avoid that, you need to use that method.
Could we not just call the ack_message() method after the
time.sleep() is over?
No, you would be calling ack_message from a different thread than the main one, that's not thread safe and prone to crashes. You need to call ack_message from a thread-safe context, i.e., the add_callback_threadsafe().
In asp.net core ViewComponent we have to implement logic in an InvokeAsync method that returns an IViewComponentResult. However I do not have any async logic to perform inside the invoke method. So based on SO post here I have removed the async qualifier and just return Task.FromResult
public Task<IViewComponentResult> InvokeAsync(MyBaseModel model)
{
var name = MyFactory.GetViewComponent(model.DocumentTypeID);
return Task.FromResult<IViewComponentResult>(View(name, model));
}
and then in View ( since I don't have async I am not using await here)
#Component.InvokeAsync("MyViewComponent", new { model = Model })
However view renders this:
System.Threading.Tasks.Task1[Microsoft.AspNetCore.Html.IHtmlContent]`
You must await the Component.InvokeAsync. The fact that your method doesn't do anything async doesn't matter. The method itself is async.
However, that's a bit of an oversimplification. Frankly, the ease of the async/await keywords belies how complicated all this actually is. To be accurate, instead of calling these types of methods "async", it's more appropriate to discuss them as "task-returning". A task is essentially a handle for some operation. That operation could be async or sync. It's most closely associated with async, simply because wrapping sync operations in a task would be pretty pointless in most scenarios. However, the point is that just because something must return a task does not also imply that it must be async.
All async does is allow the possibility of a thread switch. In scenarios where there's some operation, typically involving I/O, that would cause the working thread to be idle for some period of time, the thread becomes available to be used for other work, and the original work may complete on a different thread. Notice the use of the passive language here. Async operations can involve no thread switching; the task could complete on the same thread, as if it was sync. The task could even complete immediately, if the underlying operation has already completed.
In your scenario here, you're not doing any async work, which is fine. However, the method definition requires Task<T> as the return, so you must use Task.FromResult to return your actual result. That's all pretty standard stuff, and seems to be understood already by you. What you're missing, I think, is that you're thinking that since you're not actually doing any asynchronous work, it would be wrong to utilize await. There's nothing magical about the await keyword; it basically just means hold here until the task completes. If there's no async work to be done, as is the case here, the sync code will just run as normal and yield back to the calling code when done, However, as a convenience, await also performs one other vital function: it unwraps the task.
That is where your problem lies. Since you're not awaiting, the task itself is being returned into the Razor view processing pipeline. It doesn't know what to do with that, so it does what it does by default and just calls ToString on it, hence the text you're getting back. Unwrapped, you'd just have IViewComponentResult and Razor does know what to do with that.
If your logic performed inside the invoke method is synchronous, i.e., you don't have any await, you have 2 options:
You can define invoke method without async keyword and it should return Task.FromResult<T>
Use public IViewComponentResult Invoke() instead.
I think the async keyword enables the await keyword and that's pretty much about it. Nothing special about async keyword.
On the main thread where your view is getting rendered, since the tag helper method
to invoke a view component Component.InvokeAsync() is awaitable, you do need to put await keyword there to start the task. await examines the view component rendering to see if it has already completed. If it has, then the main thread just keeps going. Otherwise the main thread will tell the ViewComponent to run.
This might sound a bit crazy but is there a way to call a procedure synchronously?
I am using MobileFirst Platform Foundation 7.1 and I am writing an app in javascript for the browser. I usually call my javascript adapter by:
WL.Client.invokeProcedure({
adapter: 'MyAdapter',
procedure: 'myProcedureName',
parameters: []
}).then(function(res) {
...
});
But in this particular case I need to open another window after getting some data from the server. Since browsers will block windows when they come from async ajax my new windows does never open.
A way to solve this would be to do the ajax request sync. Is this possible with WL.Client apis? Is there a way for constructing the request manually so I can set the sync ajax flag by myself?
PS: in my case doing sync ajax request would work nice since I show a "Loading ..." view on top of everything to prevent user interaction while the request is being done.
WL.Client.connect() does not support .then. Additionally, starting 7.0 you should use the REST API method WLResourceRequest: https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-7-1/foundation/server-side-development-category/
Lastly, you could just put the second request in the onSuccess callback of the first...
I'm trying to implement share target app contract in win 8.1.
Sample share target app code works, but when I try to read storageItem file using following code:
storageItems.getAt(i).openReadAsync().then(function(stream) {
});
I get an error:
0x8000001f - JavaScript runtime error: A COM call to an ASTA was
blocked because the call chain originated in or passed through another
ASTA. This call pattern is deadlock-prone and disallowed by apartment
call control.
Is it another WinJs/Win8.1 preview bug or I'm doing something wrong?
I ran into this same problem. It's unfortunate that in all of the examples and tutorials and sample code that MSFT put out about share contract targets, not a single one of them actually reads the shared file.
I don't claim to understand specifically what's going on under the covers, but it involves both the UI thread of the share target (your app) and the UI thread of the share source being on the call stack at the same time during the OpenReadAsync call, which is what causes the freakout.
The solution is to move your OpenReadAsync call off of your UI thread. Sorry for not knowing the JS way of doing this, but the way I fixed my version of this problem in C# was:
// BAD - This produces: "A COM call to an ASTA was blocked because the call
// chain originated in or passed through another ASTA. This call pattern
// is deadlock-prone and disallowed by apartment call control."
//
// IRandomAccessStreamWithContentType stream = await fileReceived.OpenReadAsync();
// GOOD - This moves the OpenReadAsync off of the UI thread and works fine...
//
IRandomAccessStreamWithContentType stream = await Task.Run(async () =>
{
return await fileReceived.OpenReadAsync();
});
I was told that if I want to use predis-async, then I will use some kind of async web framework (probably built using https://github.com/reactphp/react). I am currently using Yii.
I was also told that
$client->getEventLoop()->run();
That line will start event loop which won't return after all connections to Redis are terminated and all callbacks are invoked. So that means that this line will be blocking for your code. Try to run following code (the simplest code illustrating Predis Async usage):
$client = new Predis\Async\Client('tcp://127.0.0.1:6379');
$client->set('test', 'value');
$client->getEventLoop()->run();
echo 'END';
END won't be probably displayed for a long time or maybe never, but for sure it will take more than the same operation using non-Async
Predis.
However, my own understanding is that existing PHP system should be able to use Predis Async right out of the box, as a lib. Which means existing PHP system does not need to be on ReactPHP. My idea of using predis async is similar to using mongodb asynchronous
commit. When PHP calls mongodb lib to commit a write operation, it is
asynchronous. Mongodb immediately returns the call rather than waiting for
the write happens first. In this case, mongodb doesn't requires
asynchronous php framework too.
Is it true that
END won't be probably displayed for a long time or maybe never, but
for sure it will take more than the same operation using non-Async
Predis.