7

我有一个方法,如下所示,它调用服务。

如何通过线程运行此方法?

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

3 回答 3

3

在 C# 3.5 或 4.0 中,您可以执行此操作。

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

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

在 C# 4.5 中有 await/async 关键字,这是上面的一些糖

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

var myResult = await GetAccessListOfMirror(mirrorId, server)
于 2013-05-01T13:47:14.597 回答
1

尝试这样的事情:

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;
    }
于 2013-05-01T13:47:27.450 回答
0

下面是我使用的一个辅助类,它引用了 RX.NET

如果你将它包含在你的项目中,那么你可以非常简单地线程化——上面的代码你可以分拆到一个单独的线程,如下所示:

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

值得注意的是:该 lambda 表达式被合并回原来的调用线程——例如,如果您从 GUI 线程启动异步操作,这将非常方便。

它还有另一个非常方便的方法:Fork 允许您分离多个工作线程并导致调用线程阻塞,直到所有子线程都完成或出错。

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);
                    }
                }
            });
        }
    }
}
于 2013-05-01T13:48:14.467 回答