2016-04-28 4 views
0

Ich habe diese Aufgabe Ich brauche Zeitüberschreitung, und die Ergebnisse von einem SOAP-Service innerhalb von 60 Sekunden erhalten soll.Begrenzen Task Zeit und Rückgabe, wenn die Ergebnisse erhalten, oder wenn Timeout Xamarin Formen

Die Idee ist: «SOAP, Sie haben 60 Sekunden, um mir die Ergebnisse zu erhalten; entweder sind sie hier, oder ich kann sie nicht empfangen und muss den Benutzer warnen, etwas ist schiefgelaufen. »

Sehr einfach in Englisch, aber ich habe ein paar Optionen in C# ausprobiert. und no go ...: s

Bisher habe ich versucht:

task.Wait (60000);
Task.Delay (60000);
Device.StartTimer (TimeSpan.FromMinutes (1),() => {tcs.TrySetResults (Ergebnisse); return true;});

Und wir sind immer noch nichts. Entweder wartet es die ganzen 60 Sekunden, oder wenn etwas schief geht, hört es nie auf ...

Ich bin neu in dieser Art von Operationen, also weiß ich, dass es wirklich wahrscheinlich ist, dass ich etwas wirklich Dummes mache oder etwas lake wirklich einfach, aber so oder so bin ich verloren ...

Ich benutze C# in Xamarin Forms.

Irgendwelche Hilfe, bitte?

Vielen Dank im Voraus.

EDIT: Code bilden die Seife Anfrage.

ObservableCollection<ItemDto> LoadList(string searchString) 
{ 
    TaskCompletionSource<ObservableCollection<ItemDto>> tcs = new TaskCompletionSource<ObservableCollection<ItemDto>>(); 

    ObservableCollection<ItemDto> results = new ObservableCollection<ItemDto>(); 

    try 
    { 
     MobileClient clientMobile = new MobileClient(new BasicHttpBinding(), new EndpointAddress(_endpointUrl)); 

     clientMobile.FindItemsCompleted += (object sender, FindItemsCompletedEventArgs e) => 
     { 
      _error = (e.Error != null) ? e.Error.Message : ((e.Cancelled) ? "Cancelled" : string.Empty); 

      if (string.IsNullOrWhiteSpace(_error) && e.Result.Count() > 0) 
      { 
       results = SetAdList(e.Result); 

       tcs.TrySetResult(results); 
      } 
     }; 
     clientMobile.FindItemsAsync(SetSearchParam(searchString, 100)); 
    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine("Failed to Load List. Ex: {0}", ex.ToString()); 
     return new ObservableCollection<ItemDto>(); 
    } 
    return tcs.Task.Result; 
} 

NEW EDIT

public void LoadItemList(string searchString) 
{ 
    _itemList = new ObservableCollection<ItemDto>(); 

    var result = LoadList(searchString); 

    if (result != null) 
    { 
     _itemList = result; 
    } 
    else 
    { 
     _isTaskCompleted = false; 
    } 

    _isListEmpty = (_itemList != new ObservableCollection<ItemDto>()) ? false : true; 
} 

(alle oben das tritt in ListViewModel)

Und jetzt im Code der Blick hinter nenne ich:

void Init(string searchString = "") 
{ 
    Device.BeginInvokeOnMainThread(async() => 
    { 
     if (!LoadingStackLayout.IsVisible && !LoadingActivityIndicator.IsRunning) 
     { 
      ToggleDisplayLoadingListView(true); 
     } 

     await Task.Run(() => _listVM.LoadItemList(searchString)); 

     ToggleDisplayLoadingListView(); 

     if (!string.IsNullOrWhiteSpace(_listVM.Error)) 
     { 
      await DisplayAlert("Error", _listVM.Error, "OK", "Cancel"); 
     } 
     else if (_listVM.ItemList != null && !_listVM.IsListEmpty) 
     { 
      ItemListView.IsVisible = true; 

      ItemListView.ItemsSource = _listVM.ItemList; 
     } 
     else if (!_listVM.IsTaskCompleted) 
     { 
      await DisplayAlert("Error", "Task canceled due to timeout", "OK", "Cancel"); 
     } 
     else if (_listVM.ItemList.Count == 0) 
     { 
      await DisplayAlert("", "For the moment there are no results for this search.", "OK"); 
     } 
    }); 
} 
+0

Poste den Code, der die Soap-Anfrage macht. – Giorgi

+0

'tcs.TrySetResults (Ergebnisse);' Ist eine asynchrone Version dieser Methode verfügbar (mit oder ohne Option 'CancellationToken')? – SushiHangover

+0

nicht wirklich wissen, das ist von TaskCompletionSource-Klasse, nicht eine benutzerdefinierte von mir: s –

Antwort

3

Wie ich sehe, , Sie verwenden einen BasicHTTPClient. Sie können dies versuchen:

BasicHttpBinding myBinding = new BasicHttpBinding(); 
myBinding.OpenTimeout = new TimeSpan(0, 1, 0); 
myBinding.CloseTimeout = new TimeSpan(0, 1, 0); 
myBinding.SendTimeout = new TimeSpan(0, 1, 0); 
MobileClient clientMobile = new MobileClient(myBinding, new EndpointAddress(_endpointUrl)); 

Auf der anderen Seite, sollten Sie eine Aufgabe zurückkehren> (siehe diese blog zum Beispiel) in der Ladeliste Methode. Dann können Sie einen parallelen Timer (von einem anderen question) starten

int timeout = 60000; 
var task = SomeOperationAsync(); 
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) { 
    // task completed within timeout 
} else { 
    // timeout logic 
} 
Verwandte Themen