Dưới đây là một lớp helper tôi sử dụng, nó tài liệu tham khảo RX.NET.
Nếu bạn bao gồm trong dự án của bạn, sau đó bạn có thể là thread thứ rất đơn giản - mã ở trên, bạn có thể spin off to a thread riêng biệt như sau:
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 });
Worth lưu ý: đó là biểu thức lambda là sáp nhập trở lại chủ đề gọi ban đầu - rất tiện dụng nếu bạn đang khởi tạo các hoạt động không đồng bộ của bạn từ một luồng GUI chẳng hạn.
Nó cũng có một phương pháp rất tiện dụng khác: Fork cho phép bạn tắt nhiều chuỗi công việc và làm cho chuỗi cuộc gọi chặn cho đến khi tất cả các tiểu chủ đề hoàn thành hoặc bị lỗi.
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);
}
}
});
}
}
}
Sự cố là gì? – Silvermind
Ông hỏi nếu, và sau đó làm thế nào bạn có thể chạy phương pháp đó như là một chủ đề, cho kiểu trả về của nó. –
Trường hợp nên đặt kết quả? Nếu bạn đang sử dụng C# 5, bạn nên xem [Async & Await] (http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx) –