2013-05-01 3 views
7

Ich habe eine Methode, unten gezeigt, die einen Dienst aufruft.kann eine Methode mit Rückgabetyp als Liste von einem Thread aufgerufen werden

Wie kann ich diese Methode über Thread ausführen?

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

Was ist das Problem? – Silvermind

+0

Er fragte, ob, und dann, wie Sie diese Methode als Thread ausführen können, angesichts seiner Rückgabetyp. –

+1

Wohin soll es das Ergebnis bringen? Wenn Sie C# 5 verwenden, sollten Sie sich [Async & Await] (http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx) ansehen. –

Antwort

3

In C# 3.5 oder 4.0 können Sie dies tun.

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

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

In C# 4.5 gibt es die await/Asynchron-Schlüsselwörter, die für einige Zucker über

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

var myResult = await GetAccessListOfMirror(mirrorId, server) 
1

so etwas wie dieses Versuchen:

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

Unten ist eine Hilfsklasse I, es verwenden Referenzen RX.NET.

Wenn Sie beinhalten, dass in Ihrem Projekt, dann kann man Sachen sehr einfach einfädeln - der Code über Sie zu einem separaten Thread ausgliedern könnte wie folgt aussehen:

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 }); 

Bemerkenswert: dass Lambda-Ausdruck ist Zurück zum ursprünglichen aufrufenden Thread - was sehr praktisch ist, wenn Sie beispielsweise Ihre asynchronen Vorgänge von einem GUI-Thread aus initiieren.

Es hat auch eine andere sehr praktische Methode: Fork lässt Sie mehrere Worker-Threads ausgliedern und bewirkt, dass der aufrufende Thread blockiert, bis alle Unterthreads vollständig oder fehlerhaft sind.

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); 
        } 
       } 
      }); 
     } 
    } 
} 
Verwandte Themen