我将如何同步运行asynchronous任务<T>方法?

我正在学习asynchronous/等待,并遇到了需要同步调用asynchronous方法的情况。 我怎样才能做到这一点?

asynchronous方法:

public async Task<Customers> GetCustomers() { return await Service.GetCustomersAsync(); } 

正常用法:

 public async void GetCustomers() { customerList = await GetCustomers(); } 

我已经尝试使用以下内容:

 Task<Customer> task = GetCustomers(); task.Wait() Task<Customer> task = GetCustomers(); task.RunSynchronously(); Task<Customer> task = GetCustomers(); while(task.Status != TaskStatus.RanToCompletion) 

我也从这里尝试了一个build议,但是当调度员处于暂停状态时它不起作用。

 public static void WaitWithPumping(this Task task) { if (task == null) throw new ArgumentNullException(“task”); var nestedFrame = new DispatcherFrame(); task.ContinueWith(_ => nestedFrame.Continue = false); Dispatcher.PushFrame(nestedFrame); task.Wait(); } 

以下是调用RunSynchronously的exception和堆栈跟踪:

System.InvalidOperationException

消息 :RunSynchronously可能不会被调用到未绑定到委托的任务上。

InnerException :null

来源 :mscorlib

StackTrace

  at System.Threading.Tasks.Task.InternalRunSynchronously(TaskScheduler scheduler) at System.Threading.Tasks.Task.RunSynchronously() at MyApplication.CustomControls.Controls.MyCustomControl.CreateAvailablePanelList() in C:\Documents and Settings\...\MyApplication.CustomControls\Controls\MyCustomControl.xaml.cs:line 638 at MyApplication.CustomControls.Controls.MyCustomControl.get_AvailablePanels() in C:\Documents and Settings\...\MyApplication.CustomControls\Controls\MyCustomControl.xaml.cs:line 233 at MyApplication.CustomControls.Controls.MyCustomControl.<CreateOpenPanelList>b__36(DesktopPanel panel) in C:\Documents and Settings\...\MyApplication.CustomControls\Controls\MyCustomControl.xaml.cs:line 597 at System.Collections.Generic.List`1.ForEach(Action`1 action) at MyApplication.CustomControls.Controls.MyCustomControl.<CreateOpenPanelList>d__3b.MoveNext() in C:\Documents and Settings\...\MyApplication.CustomControls\Controls\MyCustomControl.xaml.cs:line 625 at System.Runtime.CompilerServices.TaskAwaiter.<>c__DisplayClass7.<TrySetContinuationForAwait>b__1(Object state) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.Run() at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at MyApplication.App.Main() in C:\Documents and Settings\...\MyApplication\obj\Debug\App.g.cs:line 50 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() 

我发现这个解决方法适用于所有情况(包括暂停调度程序)。 这不是我的代码,我仍然努力完全理解它,但它确实有效。

它可以被调用使用:

customerList = AsyncHelpers.RunSync<List<Customer>>(() => GetCustomers());

代码是从这里

 public static class AsyncHelpers { /// <summary> /// Execute's an async Task<T> method which has a void return value synchronously /// </summary> /// <param name="task">Task<T> method to execute</param> public static void RunSync(Func<Task> task) { var oldContext = SynchronizationContext.Current; var synch = new ExclusiveSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(synch); synch.Post(async _ => { try { await task(); } catch (Exception e) { synch.InnerException = e; throw; } finally { synch.EndMessageLoop(); } }, null); synch.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); } /// <summary> /// Execute's an async Task<T> method which has a T return type synchronously /// </summary> /// <typeparam name="T">Return Type</typeparam> /// <param name="task">Task<T> method to execute</param> /// <returns></returns> public static T RunSync<T>(Func<Task<T>> task) { var oldContext = SynchronizationContext.Current; var synch = new ExclusiveSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(synch); T ret = default(T); synch.Post(async _ => { try { ret = await task(); } catch (Exception e) { synch.InnerException = e; throw; } finally { synch.EndMessageLoop(); } }, null); synch.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); return ret; } private class ExclusiveSynchronizationContext : SynchronizationContext { private bool done; public Exception InnerException { get; set; } readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false); readonly Queue<Tuple<SendOrPostCallback, object>> items = new Queue<Tuple<SendOrPostCallback, object>>(); public override void Send(SendOrPostCallback d, object state) { throw new NotSupportedException("We cannot send to our same thread"); } public override void Post(SendOrPostCallback d, object state) { lock (items) { items.Enqueue(Tuple.Create(d, state)); } workItemsWaiting.Set(); } public void EndMessageLoop() { Post(_ => done = true, null); } public void BeginMessageLoop() { while (!done) { Tuple<SendOrPostCallback, object> task = null; lock (items) { if (items.Count > 0) { task = items.Dequeue(); } } if (task != null) { task.Item1(task.Item2); if (InnerException != null) // the method threw an exeption { throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException); } } else { workItemsWaiting.WaitOne(); } } } public override SynchronizationContext CreateCopy() { return this; } } } 

被build议这个答案是三岁。 我主要是基于.Net 4.0编写的,而4.5版则很less,尤其是async-await 。 一般来说,这是一个很好的简单的解决scheme,但它有时会打破一切。 请阅读评论中的讨论。

.Net 4.5

只需使用这个:

 // For Task<T>: will block until the task is completed... var result = task.Result; // For Task (not Task<T>): will block until the task is completed... task2.RunSynchronously(); 

请参阅: TaskAwaiter , Task.Result , Task.RunSynchronously


.Net 4.0

用这个:

 var x = (IAsyncResult)task; task.Start(); x.AsyncWaitHandle.WaitOne(); 

…或这个:

 task.Start(); task.Wait(); 

在线程池上运行任务要简单得多,而不是试图诱使调度程序同步运行。 这样你就可以确定它不会死锁。 由于上下文切换,性能受到影响。

 Task<MyResult> DoSomethingAsync() { ... } // Starts the asynchronous task on a thread-pool thread. // Returns a proxy to the original task. Task<MyResult> task = Task.Run(() => DoSomethingAsync()); // Will block until the task is completed... MyResult result = task.Result; 

惊讶没有人提到这个:

 public Task<int> BlahAsync() { // ... } int result = BlahAsync().GetAwaiter().GetResult(); 

不像其他一些方法漂亮,但它有以下好处:

  • 它不会吞下exception(如Wait
  • 它不会包装在AggregateException引发的任何exception(如Result
  • 适用于TaskTask<T> ( 自己尝试一下! )

此外,由于GetAwaiter是duck-typed,这应该适用于从asynchronous方法(如ConfiguredAwaitableYieldAwaitable )返回的任何对象,而不仅仅是任务。

我正在学习asynchronous/等待,并遇到了需要同步调用asynchronous方法的情况。 我怎样才能做到这一点?

最好的答案是你不要 ,细节取决于“情况”是什么。

它是一个属性getter / setter? 在大多数情况下,asynchronous方法比“asynchronous属性”更好。 (欲了解更多信息,请参阅我的博客文章asynchronous属性 )。

这是一个MVVM应用程序,你想做asynchronous数据绑定? 然后使用像我的NotifyTask ,如我的MSDN文章中描述的asynchronous数据绑定 。

它是一个构造函数吗? 那么你可能要考虑一个asynchronous工厂方法。 (欲了解更多信息,请参阅我的博客文章asynchronous构造函数 )。

几乎总是有一个比同步asynchronous更好的答案。

如果你的情况是不可能的(你通过在这里提出一个问题来描述这种情况 ,那么我会推荐使用同步代码)。 asynchronous一路是最好的; 一路同步是次佳。 不推荐使用Sync-over-async。

但是,有一些情况需要sync-over-async。 具体来说,您受到调用代码的限制,因此您必须同步(并且绝对没有办法重新考虑或重新构造代码以允许asynchronous), 并且 必须调用asynchronous代码。 这是一个非常罕见的情况,但它不时出现。

在这种情况下,您需要使用我在关于brownfield async开发的文章中描述的一些黑客行为,具体如下:

  • 阻塞(例如, GetAwaiter().GetResult() )。 请注意, 这可能会导致死锁 (正如我在我的博客中所描述的)。
  • 在线程池线程上运行代码(例如, Task.Run(..).GetAwaiter().GetResult() )。 请注意,这只有在asynchronous代码可以在线程池线程上运行(即,不依赖于UI或ASP.NET上下文)时才有效。
  • 嵌套消息循环。 请注意,只有asynchronous代码假定单线程上下文,而不是特定的上下文types(大量的UI和ASP.NET代码需要特定的上下文),这才会工作。

嵌套的消息循环是所有黑客中最危险的,因为它会导致重入 。 重新进入是非常棘手的理由,而(IMO)是Windows上大多数应用程序错误的原因。 特别是,如果你在UI线程上,并且阻塞了一个工作队列(等待asynchronous工作完成),那么CLR实际上会为你提供一些消息 – 它实际上会处理你内部的一些Win32消息代码 。 哦,你不知道哪些信息 – 克里斯·布鲁姆Chris Brumme) 说:“确切地知道会被抽到什么不是很好吗?不幸的是,抽水是一种超出凡人理解的黑色艺术。 那么我们真的没有希望知道。

所以,当你在UI线程上这样阻塞的时候,你就会遇到麻烦。 另一篇来自同一篇文章的文章也提到:“有时候,公司内部或外部的客户发现我们在一个STA(UI线程)的pipe理阻塞期间抽出消息,这是一个合理的问题,因为他们知道这是非常困难的编写可重入的代码。“

是的。 很难写出在重入的情况下强大的代码。 嵌套的消息循环迫使你编写代码,在面临重入的时候是强健的。 这就是为什么对于这个问题,接受的(也是最高的)回答在实践中是非常危险的。

如果你完全没有其他的select – 你不能重新devise你的代码,你不能重构它是asynchronous的 – 你被不可改变的调用代码强制为同步 – 你不能改变下游代码是同步的- 你不能阻止 – 你不能在一个单独的线程上运行asynchronous代码 – 那么只有当你考虑拥抱重入。

如果你发现自己在这个angular落,我会推荐使用WPF应用程序的Dispatcher.PushFrame ,WinForm应用程序的Application.DoEvents和一般情况下,我自己的AsyncContext.Run循环。

如果我正在阅读您的问题 – 需要同步调用asynchronous方法的代码正在挂起的调度程序线程上执行。 而且,您希望实际上同步阻止该线程,直到完成asynchronous方法。

C#5中的asynchronous方法是通过将方法有效地切入底层,并返回一个Task来跟踪整个Shabang的完成。 但是,如何执行chopped的方法取决于传递给await运算符的expression式的types。

大多数情况下,您将使用types为Task的expression式。 任务的await模式的实现是“聪明的”,因为它遵循SynchronizationContext ,这基本上导致了以下情况发生:

  1. 如果进入await的线程位于Dispatcher或WinForms消息循环线程上,则确保asynchronous方法的块作为消息队列处理的一部分进行。
  2. 如果进入await的线程在线程池线程上,那么asynchronous方法的剩余块就会出现在线程池的任何地方。

这就是为什么你可能遇到问题 – asynchronous方法实现正在尝试运行Dispatcher上的其余部分 – 即使它已被暂停。

…. 备份! ….

我必须问这个问题,你为什么试图同步阻塞asynchronous方法? 这样做会打破为什么该方法想被asynchronous调用的目的。 一般来说,当您开始使用Dispatcher或UI方法的await时,您将需要将整个UIstream程asynchronous。 例如,如果您的调用堆栈如下所示:

  1. WebRequest.GetResponse()
  2. YourCode.HelperMethod()
  3. YourCode.AnotherMethod()
  4. YourCode.EventHandlerMethod()
  5. [UI代码] .Plumbing() – WPF或WinForms代码
  6. [消息循环] – WPF或WinForms消息循环

然后,一旦代码已被转换为使用asynchronous,你通常会结束

  1. WebRequest.GetResponseAsync()
  2. YourCode.HelperMethodAsync()
  3. YourCode.AnotherMethodAsync()
  4. YourCode.EventHandlerMethodAsync()
  5. [UI代码] .Plumbing() – WPF或WinForms代码
  6. [消息循环] – WPF或WinForms消息循环

实际上回答

上面的AsyncHelpers类实际上工作,因为它的行为像一个嵌套的消息循环,但它安装自己的并行机制到分派器,而不是试图在分派器本身执行。 这是您的问题的一个解决方法。

另一个解决方法是在一个线程池线程上执行你的asynchronous方法,然后等待它完成。 这样做很简单 – 您可以使用以下代码片段来完成此操作:

 var customerList = TaskEx.RunEx(GetCustomers).Result; 

最终的API将是Task.Run(…),但与CTP你需要Ex后缀( 在这里解释 )。

这对我来说很好

 public static class TaskHelper { public static void RunTaskSynchronously(this Task t) { var task = Task.Run(async () => await t); task.Wait(); } public static T RunTaskSynchronously<T>(this Task<T> t) { T res = default(T); var task = Task.Run(async () => res = await t); task.Wait(); return res; } } 

我经历了几次,主要是在unit testing或Windows服务开发中。 目前我总是使用这个function:

  var runSync = Task.Factory.StartNew(new Func<Task>(async () => { Trace.WriteLine("Task runSync Start"); await TaskEx.Delay(2000); // Simulates a method that returns a task and // inside it is possible that there // async keywords or anothers tasks Trace.WriteLine("Task runSync Completed"); })).Unwrap(); Trace.WriteLine("Before runSync Wait"); runSync.Wait(); Trace.WriteLine("After runSync Waited"); 

这很简单,容易,我没有任何问题。

我发现同步运行任务而不阻塞UI线程最简单的方法是使用RunSynchronously(),如:

 Task t = new Task(() => { //.... YOUR CODE .... }); t.RunSynchronously(); 

就我而言,当发生某些事情时,我会遇到事件。 我不知道会发生多less次。 所以,我在我的事件中使用上面的代码,所以每当它触发,它创build一个任务。 任务是同步执行的,对我来说非常有用。 我感到惊讶的是,我花了这么长时间才发现这个问题有多简单。 通常,build议要复杂得多,容易出错。 这是简单和干净。

我发现这个代码在Microsoft.AspNet.Identity.Core组件,它的工作原理。

 private static readonly TaskFactory _myTaskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default); // Microsoft.AspNet.Identity.AsyncHelper public static TResult RunSync<TResult>(Func<Task<TResult>> func) { CultureInfo cultureUi = CultureInfo.CurrentUICulture; CultureInfo culture = CultureInfo.CurrentCulture; return AsyncHelper._myTaskFactory.StartNew<Task<TResult>>(delegate { Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = cultureUi; return func(); }).Unwrap<TResult>().GetAwaiter().GetResult(); } 

只是一点点 – 这种方法:

 Task<Customer> task = GetCustomers(); task.Wait() 

适用于WinRT。

让我解释:

 private void TestMethod() { Task<Customer> task = GetCustomers(); // call async method as sync and get task as result task.Wait(); // wait executing the method var customer = task.Result; // get's result. Debug.WriteLine(customer.Name); //print customer name } public class Customer { public Customer() { new ManualResetEvent(false).WaitOne(TimeSpan.FromSeconds(5));//wait 5 second (long term operation) } public string Name { get; set; } } private Task<Customer> GetCustomers() { return Task.Run(() => new Customer { Name = "MyName" }); } 

此外,这种方法仅适用于Windows Store解决scheme!

注意:如果您在其他asynchronous方法中调用您的方法(根据@Servy的注释),这种方法不是线程安全的,

为什么不创build一个像

 Service.GetCustomers(); 

那不是asynchronous的。

在你的代码中,你首先等待任务执行,但你还没有启动它,所以它无限期地等待。 尝试这个:

 Task<Customer> task = GetCustomers(); task.RunSynchronously(); 

编辑:

你说你得到一个例外。 请张贴更多细节,包括堆栈跟踪。
单声道包含以下testing用例:

 [Test] public void ExecuteSynchronouslyTest () { var val = 0; Task t = new Task (() => { Thread.Sleep (100); val = 1; }); t.RunSynchronously (); Assert.AreEqual (1, val); } 

检查这是否适合你。 如果不是这样,虽然不太可能,但可能会有一些奇怪的Async CTP版本。 如果它确实起作用,您可能需要检查编译器生成的内容以及Task实例与此示例的不同之处。

编辑#2:

我使用Reflector进行了检查,当m_actionnull时,您所描述的exception发生了。 这有点奇怪,但我不是Async CTP的专家。 正如我所说,你应该反编译你的代码,看看究竟是如何被实例化任何如何来m_actionnull


PS什么是偶尔downvotes交易? 谨慎地阐述?

use below code snip

 Task.WaitAll(Task.Run(async () => await service.myAsyncMethod())); 

This answer is designed for anyone who is using WPF for .NET 4.5.

If you attempt to execute Task.Run() on the GUI thread, then task.Wait() will hang indefinitely, if you do not have the async keyword in your function definition.

This extension method solves the problem by checking to see if we are on the GUI thread, and if so, running the task on the WPF dispatcher thread.

This class can act as the glue between the async/await world and the non-async/await world, in situations where it is unavoidable, such as MVVM properties or dependencies on other APIs that do not use async/await.

 /// <summary> /// Intent: runs an async/await task synchronously. Designed for use with WPF. /// Normally, under WPF, if task.Wait() is executed on the GUI thread without async /// in the function signature, it will hang with a threading deadlock, this class /// solves that problem. /// </summary> public static class TaskHelper { public static void MyRunTaskSynchronously(this Task task) { if (MyIfWpfDispatcherThread) { var result = Dispatcher.CurrentDispatcher.InvokeAsync(async () => { await task; }); result.Wait(); if (result.Status != DispatcherOperationStatus.Completed) { throw new Exception("Error E99213. Task did not run to completion."); } } else { task.Wait(); if (task.Status != TaskStatus.RanToCompletion) { throw new Exception("Error E33213. Task did not run to completion."); } } } public static T MyRunTaskSynchronously<T>(this Task<T> task) { if (MyIfWpfDispatcherThread) { T res = default(T); var result = Dispatcher.CurrentDispatcher.InvokeAsync(async () => { res = await task; }); result.Wait(); if (result.Status != DispatcherOperationStatus.Completed) { throw new Exception("Error E89213. Task did not run to completion."); } return res; } else { T res = default(T); var result = Task.Run(async () => res = await task); result.Wait(); if (result.Status != TaskStatus.RanToCompletion) { throw new Exception("Error E12823. Task did not run to completion."); } return res; } } /// <summary> /// If the task is running on the WPF dispatcher thread. /// </summary> public static bool MyIfWpfDispatcherThread { get { return Application.Current.Dispatcher.CheckAccess(); } } } 

I think the following helper method could also solve the problem.

 private TResult InvokeAsyncFuncSynchronously<TResult>(Func< Task<TResult>> func) { TResult result = default(TResult); var autoResetEvent = new AutoResetEvent(false); Task.Run(async () => { try { result = await func(); } catch (Exception exc) { mErrorLogger.LogError(exc.ToString()); } finally { autoResetEvent.Set(); } }); autoResetEvent.WaitOne(); return result; } 

Can be used the following way:

 InvokeAsyncFuncSynchronously(Service.GetCustomersAsync); 

You can use CoRoutines . See Caliburn.Micro implementation. I have a custom implementation here .

Simply calling .Result; or .Wait() is a risk for deadlocks as many have said in comments. Since most of us like oneliners you can use these for .Net 4.5<

Acquiring a value via an async method:

 var result = Task.Run(() => asyncGetValue()).Result; 

Syncronously calling an async method

 Task.Run(() => asyncMethod()).Wait(); 

No deadlock issues will occur due to the use of Task.Run .

资源:

https://stackoverflow.com/a/32429753/3850405

On wp8:

Wrap it:

 Task GetCustomersSynchronously() { Task t = new Task(async () => { myCustomers = await GetCustomers(); } t.RunSynchronously(); } 

Call it:

 GetCustomersSynchronously(); 
  private int GetSync() { try { ManualResetEvent mre = new ManualResetEvent(false); int result = null; Parallel.Invoke(async () => { result = await SomeCalcAsync(5+5); mre.Set(); }); mre.WaitOne(); return result; } catch (Exception) { return null; } } 

Or you could just go with:

 customerList = Task.Run<List<Customer>>(() => { return GetCustomers(); }).Result; 

For this to compile make sure you reference extension assembly:

 System.Net.Http.Formatting 

Try following code it works for me:

 public async void TaskSearchOnTaskList (SearchModel searchModel) { try { List<EventsTasksModel> taskSearchList = await Task.Run( () => MakeasyncSearchRequest(searchModel), cancelTaskSearchToken.Token); if (cancelTaskSearchToken.IsCancellationRequested || string.IsNullOrEmpty(rid_agendaview_search_eventsbox.Text)) { return; } if (taskSearchList == null || taskSearchList[0].result == Constants.ZERO) { RunOnUiThread(() => { textViewNoMembers.Visibility = ViewStates.Visible; taskListView.Visibility = ViewStates.Gone; }); taskSearchRecureList = null; return; } else { taskSearchRecureList = TaskFooterServiceLayer .GetRecurringEvent(taskSearchList); this.SetOnAdapter(taskSearchRecureList); } } catch (Exception ex) { Console.WriteLine("ActivityTaskFooter -> TaskSearchOnTaskList:" + ex.Message); } }