使用C#的.NET 4.0中,Task.Run的替代方法是什么?

77

我使用的VB 2010 .NET 4.0程序出现了语法错误:“System.Threading.Tasks.task中不包含Run的定义。”

有什么想法吗?在.NET 4.0中是否有任何替代方法来运行程序?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ChatApp
{
class ChatProg
{
    static void Main(string[] args)
    {
        Task<int> wakeUp = DoWorkAsync(2000,"Waking up");
        Task.WaitAll(wakeUp);
    }

    static Task<int> DoWorkAsync(int milliseconds, string name)
    {

        //error appears below on word Run
        return Task.Run(() =>
            {
                Console.WriteLine("* starting {0} work", name);
                Thread.Sleep(milliseconds);
                Console.WriteLine("* {0} work one", name);
                return 1;
            });
    }
}
}

4
试试这个 Task.Factory.StartNew() 方法。 请参考以下链接:http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx - Saroop Trivedi
我遇到了同样的问题,但是在阅读有关此问题的内容时发现它存在风险。那么使用线程是一个好选择吗?如果是,请提供有关线程的详细信息和示例,因为这是我第一次使用线程。 - sam
4个回答

90

看起来你需要使用Task.Factory.StartNew<T>

return Task.Factory.StartNew<int>(() => {
    // ...
    return 1;
});

由于编译器可以推断返回类型,因此这也适用:

return Task.Factory.StartNew(() => {
    // ...
    return 1;
});

2
运行是.NET 4.5的功能吗? - Ace Caserya
3
是的,显然如此:http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.run.aspx - McGarnagle
3
补充回答,我找到了这个链接:http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx - Ace Caserya
1
在C++/CLI中,似乎是Task::Factory->StartNew。 - Miroslav Nedyalkov
5
重要的是要知道这个代码与 Task.Run 的行为并不完全相同。 - usr

10

不幸的是,得票最高的答案并不完全正确

不幸的是,只有使用TaskScheduler的StartNew重载需要指定CancellationToken和TaskCreationOptions。这意味着为了可靠、可预测地将工作排队到线程池中,您必须使用以下类似的重载:

Task.Factory.StartNew(A, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

因此,在4.0中最接近Task.Run的东西是:

/// <summary>
/// Starts the new <see cref="Task"/> from <paramref name="function"/> on the Default(usually ThreadPool) task scheduler (not on the TaskScheduler.Current).
/// It is a 4.0 method nearly analogous to 4.5 Task.Run.
/// </summary>
/// <typeparam name="T">The type of the return value.</typeparam>
/// <param name="factory">The factory to start from.</param>
/// <param name="function">The function to execute.</param>
/// <returns>The task representing the execution of the <paramref name="function"/>.</returns>
public static Task<T> StartNewOnDefaultScheduler<T>(this TaskFactory factory, Func<T> function)
{
    Contract.Requires(factory != null);
    Contract.Requires(function != null);

    return factory
        .StartNew(
            function,
            cancellationToken: CancellationToken.None,
            creationOptions: TaskCreationOptions.None,
            scheduler: TaskScheduler.Default);
}

可以像这样使用:

Task
    .Factory
    .StartNewOnDefaultScheduler(() => 
        result);

5

我使用了 Task.Factory.StartNew 修改了你的代码,详细信息请参考链接

 static Task<int> DoWorkAsync(int milliseconds, string name)
        {


            //error appears below on word Run
            return   Task.Factory.StartNew(() =>
            {
                Console.WriteLine("* starting {0} work", name);
                Thread.Sleep(milliseconds);
                Console.WriteLine("* {0} work one", name);
                return 1;
            });
        }

3

如果你正在使用Microsoft.Bcl.Async,那么这里有一些信息:

return TaskEx.Run(() =>
{
    Console.WriteLine("* starting {0} work", name);
    Thread.Sleep(milliseconds);
    Console.WriteLine("* {0} work one", name);
    return 1;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接