如何在以下场景中使用线程或任务模式

时间:2014-01-20 14:31:18

标签: c# multithreading

我在Main方法中使用了两种方法,比如

public bool isBadMethod() 
{ 
   bool isBad = Method1();
   if(isBad) return true; 
   else return Method2(); 
}

bool Method1() { ..... return true or false }         
bool Method2() { ..... return true or false }

如果Method1或Method2中的任何一个返回true,则无需检查其他方法,我们可以将MainMethod返回为true。但是如果第一个方法返回false则需要检查第二个方法并最终返回第二个方法返回的内容。这里Method1和Method2是耗时的方法。我可以在这些方法上使用异步编程吗?帮忙怎么做。 (我正在使用.net 4.0)

3 个答案:

答案 0 :(得分:4)

你可以利用表达式的短路:

bool val = Method1() || Method2();

如果Method1返回true,则不会对第二种方法感到烦恼。

显然,如果方法调用很昂贵,那么继续执行任务路由,因为这不是并行执行。我只是张贴这个,以防它是一个XY问题。

<小时/> 使用任务,这可能就像你想要的那样。它将运行两种方法,然后只使用表达式来获取正确的结果。在这种情况下,它等待整整3秒来获取Method2的结果。这也取消了。我不确定所使用的类型是否是最佳实践,因为我对此的体验不完整,但它可以在我的沙箱中完成工作:

internal class Program
{
    private static void Main(string[] args)
    {
        var cm2 = new CancellationTokenSource();

        var m1 = Task.Factory.StartNew(() => Method1());
        var m2 = Task.Factory.StartNew(() => Method2(cm2.Token), cm2.Token);

        var val = m1.Result || m2.Result;

        cm2.Cancel();

        Console.WriteLine(val);
        Console.ReadLine();
    }

    private static bool Method1()
    {
        Thread.Sleep(1000);
        Console.WriteLine(1);
        return true;
    }

    private static bool Method2(CancellationToken token)
    {
        Thread.Sleep(3000);

        if (token.IsCancellationRequested)
            return false;

        Console.WriteLine(2);
        return true;
    }
}

正如Matthew Watson在评论中指出的那样,Method2需要使用取消令牌才能实际“取消”。在我的例子中,它只是停止打印数字并提前返回。

答案 1 :(得分:3)

如果你不关心Method2()在Method1()返回后是否继续运行,那么做这样的事情并不困难:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Demo
{
    internal class Program
    {
        private void run()
        {
            Stopwatch sw = Stopwatch.StartNew();
            bool result = test();
            Console.WriteLine("Returned " + result + " after " + sw.Elapsed);
        }

        private bool test()
        {
            var method1 = Task.Run(new Func<bool>(Method1));
            var method2 = Task.Run(new Func<bool>(Method2));

            return method1.Result || method2.Result;
        }

        public bool Method1()
        {
            Console.WriteLine("Starting Method1()");
            Thread.Sleep(2000);
            Console.WriteLine("Returning from Method1()");
            return true;
        }

        public bool Method2()
        {
            Console.WriteLine("Starting Method2()");
            Thread.Sleep(3000);
            Console.WriteLine("Returning true from Method2()");
            return true;
        }

        private static void Main()
        {
            new Program().run();
        }
    }
}

Method1()需要2秒才能完成。 Method1()需要3秒钟才能完成。

当你运行此方法并将Method1()设置为返回true时,总时间约为2秒 - 这是Method1()的运行时间。

如果编辑Method1()使其返回false,则总时间约为3秒 - Method2()的运行时间。

所以你可以看到它没有按顺序运行这两个任务。这种方法是“投机执行”的一种形式。

但是,如果在Method1()返回true时必须取消Method2(),则会变得更复杂。

答案 2 :(得分:1)

使用任务,您的逻辑可以像这样执行:

System.Threading.Tasks.Task.Factory                     
    .StartNew<bool>(        
        () => {  return Method1(); })        
    .ContinueWith<bool>(prev =>        
        {                        
            if (!prev.Result)                                
                return Method2();
            else
                return true;         
        })
    .ContinueWith(prev =>        
        {                        
            // do something with prev.Result
        })

请注意,您可以在第二个任务中执行第三个任务中的逻辑,或者甚至只在一个任务中执行所有操作,这取决于您的要求。例如,您可能需要将第三个任务与UI同步。