Hi I am using this DeleteObjectsAsync and it doesn't work in a way that it looks like it stops, and it doesn't execute the next line and nothing is deleted.
I added try catch but it isn't going to any of the catches. But if I use the non-async one DeleteObjects, it works but I had to put a .Wait() like this client.DeleteObjects(deleteObjectRequest).Wait() otherwise it stops also like the DeleteObjectsAsync. It stops in a way that the RUN is still on but it just flickers after calling the delete and will not execute the next lines of codes as if it already reached the last line of it. How to make this work? thanks
My code
public static async Task<bool> DeleteFilesFromS3Async(List<KeyVersion> keyVersions, string bucketName = "")
{
try
{
using (var client = new AmazonS3Client(AmazonKey, AmazonSecretKey, AmazonRegion))
{
var deleteObjectRequest = new DeleteObjectsRequest { BucketName = bucketName , Objects = keyVersions };
await client.DeleteObjectsAsync(deleteObjectRequest);
return true;
}
}
catch (DeleteObjectsException e)
{
return false;
}
catch (AmazonS3Exception e)
{
return false;
}
catch (Exception x)
{
return false;
}
}
Make sure you are calling it the right way.
Either, caller method must be async and you must be using await there.
public async Task DeleteFile()
{
var result = await DeleteFilesFromS3Async(...);
}
Or, invoke this method synchronously.
public void DeleteFile()
{
var result = DeleteFilesFromS3Async(...).Result;
}
Related
The test method is always failing. After the Setup the method UpdateAsync should return 1 in the result but it remains always 0 which results in exception in the controller method.
Can you tell what I am missing here ?
[Test]
public async Task UpdateImportHeaderAsyncTest()
{
//Arrange
HeaderRequest request = new HeaderRequest()
{
ConfigurationId = 1,
Key = "1",
Status = 1
};
_manager.Setup(a => a.UpdateAsync(_mockData.Header)).Returns(Task.FromResult(1));
//Act
var actual = await Controller.UpdateHeaderAsync(request);
//Assert
Assert.NotNull(actual);
}
//Controller Method
[HttpPut]
public async Task<int> UpdateHeaderAsync(HeaderRequest request)
{
var result = 0;
try
{
result = await _manager.UpdateAsync(new Header()
{
HeaderId = request.Id,
Status = request.Status,
ConfigurationId = request.ConfigurationId
});
if (result == 0)
{
throw new RecordNotFoundException("No records found.", "1", "");
}
}
catch (Exception ex)
{
throw;
}
return result;
}
Loosen the argument match using It.IsAny<Header>()to get the desired behavior.
//...
_manager
.Setup(a => a.UpdateAsync(It.IsAny<Header>()))
.ReturnsAsync(1);
//...
The setup also allows for ReturnsAsync for setting up async members.
What was happening before was that you were setting it up with a specific referenced instance. That instance was not the same one used when exercising the test since you initialized a new Header. This caused the mock to return the default value for the return type.
Reference Moq Quickstart to get a better understanding of how to use the framework
I have async method ExecuteWithRetryAsync which implements some retry logic and must show ProgressDialog as soon as it is called. Currently the first call to Show() never really works. The progress dialog shows only after the AlertDialog is confirmed (second comment). How do I make Show() at the beginning of ExecuteWithRetryAsync actually show the progress dialog?
public async Task<object> ExecuteWithRetryAsync(string methodName, object[] args)
{
MethodInfo methodInfo = typeof(Service1).GetMethod(methodName);
// below progress dialog not showing
mDialog = new ProgressDialog(context);
mDialog.SetMessage("Bitte warten...");
mDialog.SetCancelable(false);
mDialog.Show();
for (; ; )
{
try
{
object result = null;
try
{
// Call web service.
result = methodInfo?.Invoke(webservice, args);
}
catch (TargetInvocationException tie)
{
if (tie.InnerException != null) throw tie.InnerException;
}
mDialog?.Dismiss();
return result;
}
catch (Exception e)
{
Trace.TraceError("Operation Exception");
currentRetry++;
if (/*currentRetry > RetryCount || */!IsTransient(e))
{
// If this isn't a transient error or we shouldn't retry,
// rethrow the exception.
throw;
}
}
mDialog?.Dismiss();
await DisplayAlert(
context.GetString(Resource.String.timeout),
context.GetString(Resource.String.retry_operation),
context.GetString(Resource.String.Ok),
methodInfo);
// this progress dialog is showing
mDialog = new ProgressDialog(context);
mDialog.SetMessage("Bitte warten...");
mDialog.SetCancelable(false);
mDialog.Show();
await Task.Delay(MaxDelayMilliseconds);
}
}
UPDATE: I observed that when connection of device is disabled it takes about ~10-15 secs for ExecuteWithRetryAsync to start execution and in the meantime device shows app not responding dialog several times, whereas with the connection on it executes immediately. Why that?
UPDATE 2: When I put await Task.Delay (50) after calling Show() it does show, but the progress dialog animation is not updating, it's frozen.
UPDATE 3: I put following line result = methodInfo?.Invoke(Utility.WsHueckmann, args) inside await Task.Run so it becomes await Task.Run(() => { result = methodInfo?.Invoke(Utility.WsHueckmann, args); }) and now it's working and spinner is updating.
The reason behind your progress not spinning is because it is not indeterminate add the following code and it should work
progress.Indeterminate = true;
progress.SetProgressStyle(Android.App.ProgressDialogStyle.Spinner);
Update
Put the following line
result = methodInfo?.Invoke(Utility.WsHueckmann, args)
inside await Task.Run so it becomes
await Task.Run(() => { result = methodInfo?.Invoke(Utility.WsHueckmann, args); })
and now it's working and spinner is updating.
I have a routine which gets a list of filenames from the device, then reads the file(s) to build a list. However, the calling routine always returns with zero items. I print the filenames, so I know they exist, however, it appears that the async is returning before I read the files. I used similar code when making an HTTP call. But, something here is causing the routine to return the list even though it hasn't completed. Perhaps, it is possible that I am calling it at the wrong time? I am calling retrieveItems here:
#override
void initState() {
super.initState();
retrieveItems();
}
Eventually I will have a refresh button, but for now I'd simply like the list to populate with the data from the files...
--------------------
Callee
Future<List<String>> readHeaderData() async {
List<String> l = new List();
List<String> files = await readHeaders(); // Gets filenames
files.forEach((filename) async {
final file = await File(filename);
String contents = await file.readAsString();
User usr = User.fromJson(json.decode(contents));
String name = usr.NameLast + ", " + usr.NameFirst;
print(name);
l.add(name);
}
return l;
Caller
void retrieveItems() async {
LocalStorage storage = new LocalStorage();
await storage.readHeaderData().then((item) {
try {
if ((item != null ) &&(item.length >= 1)) {
setState(() {
users.clear();
_users.addAll(item);
});
} else {
setState(() {
_users.clear();
final snackbar = new SnackBar(
content: new Text('No users found.'),
);
scaffoldKey.currentState.showSnackBar(snackbar);
});
}
} on FileNotFoundException catch (e) {
print(e.toString()); //For debug only
setState(() {
_users.clear();
});
});
}
});
This code
Future<List<String>> readHeaderData() async {
List<String> l = new List();
List<String> files = await readHeaders(); // Gets filenames
files.forEach((filename) async {
final file = await File(filename);
String contents = await file.readAsString();
User user = User.fromJson(json.decode(contents));
String name = user.NameLast + ", " + user.NameFirst;
print(name);
l.add(name);
}
return l;
}
returns the list l and then processes the asyc forEach(...) callbacks
If you change it to
Future<List<String>> readHeaderData() async {
List<String> l = new List();
List<String> files = await readHeaders(); // Gets filenames
for(var filename in files) { /// <<<<==== changed line
final file = await File(filename);
String contents = await file.readAsString();
User user = User.fromJson(json.decode(contents));
String name = user.NameLast + ", " + user.NameFirst;
print(name);
l.add(name);
}
return l;
}
the function will not return before all filenames are processed.
files.forEach((filename) async {
means that you can use await inside the callback, but forEach doesn't care about what (filename) async {...} returns.
Also possible
await Future.forEach(yourList, (T elem) async { ...async staff });
To expand on Günter's comment regarding using list.map(f), here's an example of converting a forEach call so that it works correctly.
Broken example
Incorrectly assumes forEach will wait on futures:
Future<void> brokenExample(List<String> someInput) async {
List<String> results;
someInput.forEach((input) async {
String result = await doSomethingAsync(input);
results.add(result);
});
return results;
}
Corrected example
Waits on the async functions to complete, using Future.wait and .map():
Future<void> correctedExample(List<String> someInput) async {
List<String> results;
await Future.wait(someInput.map((input) async {
String result = await doSomethingAsync(input);
results.add(result);
}));
return results;
}
I encountered the similar issue. The problem is that dart will NOT wait for "forEach" contrary to public believe. There are two solutions:
1) Convert forEach to for loop as indicated by others. Another is use Future:
2) await Future.forEach(list, (item) async {
// your code
final result = await getMyResult();
});
Another option
Future.wait(someList.map((item) => something_returns_future(item)));
I have a vertx handler code where I do an executeBlocking but for it to work I need to put in a Thread.sleep() in order for the code in the blocking code to fully execute to the point that I can check the results.
Is there a better way around this so I don't do a Thread.sleep?
My handler code the following is the portion where I only kept the relevant components.
try (final VertxHttpResponse response = new VertxHttpResponse(context)) {
context.vertx().executeBlocking(
future -> {
...
try {
dispatcher.invokePropagateNotFound(request,
response);
future.complete();
} finally {
...
}
}, false,
res -> {
if (res.failed()) {
context.fail(wae);
} else {
if (!context.response().ended()) {
context.response().end();
}
}
});
} catch (final IOException e) {
throw new UncheckedIOException(e);
}
}
My test and the relevant parts
#Test
public void test(final TestContext testContext) throws Exception {
final Router router = Router.router(rule.vertx());
final SpringJaxRsHandler handler = SpringJaxRsHandler.registerToRouter(router, MyApp.class);
final RoutingContext routingContext = mock(RoutingContext.class);
when(routingContext.currentRoute()).thenReturn(router.get("/api/hello"));
when(routingContext.vertx()).thenReturn(rule.vertx());
final HttpServerRequest serverRequest = mock(HttpServerRequest.class);
when(serverRequest.absoluteURI()).thenReturn("/api/hello");
when(serverRequest.isEnded()).thenReturn(true);
when(serverRequest.method()).thenReturn(HttpMethod.GET);
when(routingContext.request()).thenReturn(serverRequest);
final HttpServerResponse response = mock(HttpServerResponse.class);
when(response.putHeader(anyString(), anyString())).thenReturn(response);
when(response.headers()).thenReturn(new VertxHttpHeaders());
when(routingContext.response()).thenReturn(response);
handler.handle(routingContext);
Thread.sleep(1000);
// fails without the sleep above
verify(response, times(1)).setStatusCode(200);
}
I tried
testContext.assertTrue(routingContext.response().ended());
But that returned false.
I refactored the code a bit so I don't use routingContext directly but the concept is still the same. I use Async in combination of a when->then(Answer) and have the async.complete() be called in the Answer. Once that is done do an async.await() to wait for the thread to finish.
final Async async = testContext.async();
when(response.write(Matchers.any(Buffer.class))).then(invocation -> {
try {
return response;
} finally {
async.complete();
}
});
when(serverRequest.response()).thenReturn(response);
router.accept(serverRequest);
async.await();
assume the code is correct and webservice timeout occurs.
The problem :
The system crashes and can not display the error message.
How to display error message? So I can provide an alternative to user when there is an error?
1)
I add this Class in the project :
public class MyClass
{
public static async Task LogInSuccess()
{
try
{
-- calling a web service here
}
catch (System.Exception _ex)
{
_strErrorMsg = _ex.InnerException.Message;
throw new Exception("LogInSuccess() " + _strErrorMsg);
}
}
}
--- In the MainPage,
2)
private async void SetUp ()
{
-- code for doing setUp task--
CallWebSvc();
}
3)
private void CallWebSvc()
{
bool ShowError = false;
System.Exception MyException = new Exception();
try
{
-- calling a web service thru the MyClass
System.Threading.Tasks.Task _blnLogInSuccess = MyClass.LogInSuccess();
await _blnLogInSuccess;
if (_blnLogInSuccess.IsCompleted)
{
g_blnLoginStatus = _blnLogInSuccess.Result;
}
}
catch (System.Exception _ex)
{
ShowError = true;
MyException = ex;
}
if (ShowError)
{
var MyMessageBox = new Windows.UI.Popups.MessageDialog("Remote Login Error:" + MyException.Message, "Start Login" );
await MyMessageBox.ShowAsync();
}
}
I assume your CallWebSvc method is async void (as, without async you cannot perform an await) If this is the case, you need to know async void doesn't do the same treatament to exceptions as async task. they aren't catched correctly. If you change your CallWebSvc from async void to async Task, you are going to receive the exception correctly.