Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在以下场景中使用线程或任务模式_C#_Multithreading - Fatal编程技术网

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

C# 如何在以下场景中使用线程或任务模式,c#,multithreading,C#,Multithreading,我有两种方法在像这样的主要方法中使用 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或Metho

我有两种方法在像这样的主要方法中使用

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,那个么需要检查第二个方法,最后返回第二个方法返回的内容。这里的方法1和方法2都是耗时的方法。我可以在这些方法上使用异步编程吗。帮助如何做。(我正在使用.net 4.0)

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

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
需要使用取消令牌才能真正“取消”。在我的示例中,它只是停止打印数字并提前返回。

使用任务,您的逻辑可以如下执行:

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
        })
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();
        }
    }
}
System.Threading.Tasks.Task.Factory
.StartNew(
()=>{return Method1();})
.ContinueWith(上一个=>
{                        
如果(!上一个结果)
返回方法2();
其他的
返回true;
})
.ContinueWith(上一个=>
{                        
//对上一个结果做点什么
})

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

如果您不关心Method1()返回后Method2()是否继续运行,那么执行以下操作并不困难:

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
        })
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();
        }
    }
}
使用系统;
使用系统诊断;
使用系统线程;
使用System.Threading.Tasks;
名称空间演示
{
内部课程计划
{
私家车
{
秒表sw=Stopwatch.StartNew();
bool结果=测试();
Console.WriteLine(“在“+sw.passed”之后返回“+result+”);
}
私人布尔测试()
{
var method1=Task.Run(newfunc(method1));
var method2=Task.Run(newfunc(method2));
返回方法1.结果| |方法2.结果;
}
公共布尔方法1()
{
WriteLine(“启动方法1()”);
《睡眠》(2000年);
WriteLine(“从Method1()返回”);
返回true;
}
公共布尔方法2()
{
WriteLine(“启动方法2()”);
睡眠(3000);
WriteLine(“从Method2()返回true”);
返回true;
}
私有静态void Main()
{
新程序().run();
}
}
}
Method1()需要2秒钟才能完成。 Method1()需要3秒钟才能完成

在Method1()设置为返回true的情况下运行时,总时间约为2秒,这是Method1()的运行时间

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

因此,您可以看到它并没有按顺序运行这两个任务。这种做法是一种“投机执行”


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

理论上,您可以在单独的任务中开始这两个任务。然后,如果Method1()返回true,则取消Method2();否则,等待Method2()完成。这取决于您可以取消Method2(),这与我的答案非常相似,但我键入得太慢了。:)我想指出的是,取消令牌必须在task方法中实际使用,否则它不会做任何事情