C#(.NET)中类似Android AsyncTask的功能

时间:2011-09-15 12:18:06

标签: c# java android .net task

您可能知道,Android的SDK具有AsyncTask类,允许在单独的线程上执行代码并在主(UI)线程中获取结果。简而言之,就像这样:

class AsyncTask
{
   void onPreExecute(...)
   {
       //Executed on the main thread BEFORE the secondary thread gets to work on anything.
   }

   void execute(...)
   {
       //This runs on the secondary thread.
   }

   void onPostExecute(...)
   {
       //This runs on the main thread AFTER the secondary thread finishes work. You get the result here in the form of some data type.
   }
}

当然,这只是一个粗略的方案,但如果您不熟悉它,它应该提供有关AsyncTask的足够信息。基本上,我在微软的.NET Framework中寻找相同的功能。

在我开始自己的课程之前,我想确保没有任何东西可以让我在框架中获得所需的结果。我正在使用.NET 4.0。也许某种“聪明”的使用System.Threading.Tasks.Task?我不知道,我会留给你的。

简而言之,我想将一些输入传递给函数,在辅助线程上运行代码,并在完成时通过主线程更新一些UI元素。锁定主线程(例如通过Task.Wait())不能很好地满足我的要求。

2 个答案:

答案 0 :(得分:2)

您可以使用.Net中的Task课程来实现您的目标。

以下是一些有助于您入门的代码:

var task = Task.Factory.StartNew(() => YourMethodGoesHere());

task.ContinueWith(t => UpdateYourUiInThisContinuation(),
                  TaskScheduler.FromCurrentSynchronizationContext());

task.ContinueWith(t => HandleAnExceptionWhichTheTaskMayThrow(), 
                   TaskContinuationOptions.OnlyOnFaulted);

这将安排YourMethodGoesHere()运行UI线程。继续,UpdateYourUiInThisContinuation()将被安排在初始任务完成后运行,并且我使用的重载将强制它在同一个同步上下文中继续(UI线程,假设最初在UI线程上调用此代码)

最后一个延续是处理任务中可能抛出的代码的任何异常的好习惯。如果你不处理它(除了使用这个延续之外还有其他方法),你最终会得到一个未处理的AggregateException。

答案 1 :(得分:1)

您可以使用BackgroundWorker类创建一个抽象类

public abstract class AsyncTask
{
    private BackgroundWorker bw;

    public AsyncTask()
    {
        bw = new BackgroundWorker();
        bw.DoWork += (s,e)=> { DoInBackground(); };
        bw.RunWorkerCompleted += (s, e) => { TaskCompleted(); };
    }

    protected abstract void PreExecute();
    protected abstract void DoInBackground();
    protected abstract void TaskCompleted();

    public void Execute() {
        PreExecute();
        bw.RunWorkerAsync();
    }
}

像Android中的AsyncTask一样实现

private class ExampleTask : AsyncTask
    {
        protected override void DoInBackground()
        {
            //Background process. 2nd thread
        }

        protected override void PreExecute()
        {
            //Main thread. Before executing DoInBackground
        }

        protected override void TaskCompleted()
        {
            //Main thread. Task Completed
        }
    }

并调用Execute()

new ExampleTask().Execute();