2013-05-01 12 views
7

Mam metodę, pokazaną poniżej, która wywołuje usługę.można wywołać metodę z typem zwracania jako listę z wątku

Jak uruchomić tę metodę za pomocą wątku?

public List<AccessDetails> GetAccessListOfMirror(string mirrorId,string server) 
{ 
    List<AccessDetails> accessOfMirror = new List<AccessDetails>(); 
    string loginUserId = SessionManager.Session.Current.LoggedInUserName; 
    string userPassword = SessionManager.Session.Current.Password; 

    using (Service1Client client = new Service1Client()) 
    { 
     client.Open(); 
     accessOfMirror = client.GetMirrorList1(mirrorId, server, null); 
    } 

    return accessOfMirror; 
} 
+1

Na czym polega problem? – Silvermind

+0

Zapytał, czy, a następnie w jaki sposób można uruchomić tę metodę jako wątek, biorąc pod uwagę jego typ zwracany. –

+1

Gdzie powinien umieścić wynik? Jeśli używasz C# 5, powinieneś spojrzeć na [Async & Await] (http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx) –

Odpowiedz

3

W języku C# 3.5 lub 4.0 można to zrobić.

var task = Task.Factory.StartNew<List<AccessDetails>>(() => GetAccessListOfMirror(mirrorId,server)) 
.ContinueWith(tsk => ProcessResult(tsk)); 

private void ProcessResult(Task task) 
{ 
    var result = task.Result; 
} 

w C# 4.5 nie ma słów kluczowych Oczekujcie/async który jakiś cukier dla wyżej

public async Task<List<AccessDetails>> GetAccessListOfMirror(string mirrorId,string server) 

var myResult = await GetAccessListOfMirror(mirrorId, server) 
1

Spróbuj czegoś takiego:

public async Task<List<AccessDetails>> GetAccessListOfMirror(string mirrorId, string server) 
    { 
     List<AccessDetails> accessOfMirror = new List<AccessDetails>(); 
     string loginUserId = SessionManager.Session.Current.LoggedInUserName; 
     string userPassword = SessionManager.Session.Current.Password; 


     using (Service1Client client = new Service1Client()) 
     { 
      client.Open(); 
      Task<List<AccessDetails>> Detail = client.GetMirrorList1(mirrorId, server, null); 
      accessOfMirror = await Detail; 

     } 


     return accessOfMirror; 
    } 
0

Poniżej znajduje się klasa pomocnika go używać, referencje RX.NET.

Jeśli to, że w projekcie, można wkręcić rzeczy bardzo prosto - kod powyżej was mógłby wydzielić do osobnego wątku, co następuje:

int mirrorId = 0; 
string server = "xxx"; 
ASync.Run<List<AccessDetails>>(GetAccessListOfMirror(mirrorId,server), resultList => { 
    foreach(var accessDetail in resultList) 
    { 
     // do stuff with result 
    } 
}, error => { // if error occured on other thread, handle exception here }); 

Warto zauważyć: że wyrażenie lambda wróciłem do pierwotnego wątku wywołującego - co jest bardzo przydatne, jeśli np. inicjujesz operacje asynchroniczne z wątku GUI.

Posiada również inną bardzo przydatną metodę: Widelec pozwala odłączyć wiele wątków roboczych i powoduje, że wątek wywołujący blokuje się, aż wszystkie pod-wątki zostaną zakończone lub skasowane.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Concurrency; 

namespace MyProject 
{ 

    public static class ASync 
    { 
     public static void ThrowAway(Action todo) 
     { 
      ThrowAway(todo, null); 
     } 

     public static void ThrowAway(Action todo, Action<Exception> onException) 
     { 
      if (todo == null) 
       return; 

      Run<bool>(() => 
      { 
       todo(); 
       return true; 
      }, null, onException); 
     } 

     public static bool Fork(Action<Exception> onError, params Action[] toDo) 
     { 
      bool errors = false; 
      var fork = Observable.ForkJoin(toDo.Select(t => Observable.Start(t).Materialize())); 
      foreach (var x in fork.First()) 
       if (x.Kind == NotificationKind.OnError) 
       { 
        if(onError != null) 
         onError(x.Exception); 

        errors = true; 
       } 

      return !errors; 
     } 

     public static bool Fork<T>(Action<Exception> onError, IEnumerable<T> args, Action<T> perArg) 
     { 
      bool errors = false; 
      var fork = Observable.ForkJoin(args.Select(arg => Observable.Start(() => { perArg(arg); }).Materialize())); 
      foreach (var x in fork.First()) 
       if (x.Kind == NotificationKind.OnError) 
       { 
        if (onError != null) 
         onError(x.Exception); 

        errors = true; 
       } 

      return !errors; 
     } 


     public static void Run<TResult>(Func<TResult> todo, Action<TResult> continuation, Action<Exception> onException) 
     { 
      bool errored = false; 
      IDisposable subscription = null; 

      var toCall = Observable.ToAsync<TResult>(todo); 
      var observable = 
       Observable.CreateWithDisposable<TResult>(o => toCall().Subscribe(o)).ObserveOn(Scheduler.Dispatcher).Catch(
       (Exception err) => 
       { 
        errored = true; 

         if (onException != null) 
          onException(err); 


         return Observable.Never<TResult>(); 
       }).Finally(
       () => 
       { 
        if (subscription != null) 
         subscription.Dispose(); 
       }); 

      subscription = observable.Subscribe((TResult result) => 
      { 
       if (!errored && continuation != null) 
       { 
        try 
        { 
         continuation(result); 
        } 
        catch (Exception e) 
        { 
         if (onException != null) 
          onException(e); 
        } 
       } 
      }); 
     } 
    } 
} 
Powiązane problemy