Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.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# 何时使用Task.Run和not_C#_Task - Fatal编程技术网

C# 何时使用Task.Run和not

C# 何时使用Task.Run和not,c#,task,C#,Task,我昨天问了这个问题,但仍然不明白使用中的区别 task = Task.Run(() => RunLongRunningMethod(cts.Token)); 及 我已经通读了,它似乎主要使用任务。只要正确使用它,就可以运行(不在实现中) 关于这一点,还有其他的阅读材料吗?或者有人能解释一下两者之间的区别吗 下面是我的代码,使用这两种方法都可以正常工作 using System; using System.Collections.Generic; using System.Componen

我昨天问了这个问题,但仍然不明白使用中的区别

task = Task.Run(() => RunLongRunningMethod(cts.Token));

我已经通读了,它似乎主要使用任务。只要正确使用它,就可以运行(不在实现中)

关于这一点,还有其他的阅读材料吗?或者有人能解释一下两者之间的区别吗

下面是我的代码,使用这两种方法都可以正常工作

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private static HttpClient client { get; set; }
        private Task task { get; set; }
        private CancellationTokenSource cts { get; set; }
        private bool buttonStartStopState { get; set; }

        public Form1()
        {
            InitializeComponent();
        }

        private async Task RunLongRunningMethod(CancellationToken cancellationToken)
        {
            try
            {
                while (true)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                    }

                    // Some CPU bound work here

                    // Then call async
                    var success = await GetUrlAsync(@"https://www.bbc.co.uk/");
                    Thread.Sleep(2000); // simulate blocking only
                }
            }
            catch (OperationCanceledException)
            {
                // Just exit without logging. Operation cancelled by user.
            }
            catch (Exception ex)
            {
                // Report Error
            }
        }

        private async Task<bool> GetUrlAsync(string url)
        {
            if (client == null)
            {
                client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true, AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip });
                client.BaseAddress = new Uri("https://www.bbc.co.uk/");
                client.DefaultRequestHeaders.Add("Accept", "*/*");
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/62.0");
                client.DefaultRequestHeaders.Connection.Add("Keep-Alive");
                client.DefaultRequestHeaders.Add("DNT", "1");
            }

            var response = await client.GetAsync(url);
            var contents = await response.Content.ReadAsStringAsync();

            Debug.WriteLine($"{DateTime.Now} {response.StatusCode}");
            return true;
        }

        private void buttonStartStop_Click(object sender, EventArgs e)
        {
            buttonStartStopState = !buttonStartStopState;
            if(buttonStartStopState)
            {
                cts = new CancellationTokenSource();

                // What is difference between this
                //task = Task.Run(() => RunLongRunningMethod(cts.Token));

                // And this?
                task = RunLongRunningMethod(cts.Token);

                // This always runs instantly
                Debug.WriteLine($"{DateTime.Now} buttonStartStopState:{buttonStartStopState}");
            }
            else
            {
                cts.Cancel();
                cts = null;
            }
        }

        private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(cts != null)
            {
                cts.Cancel(); // CancellationTokenSource
                cts = null;
            }

            if (!task.IsCompleted)
            {
                //this.Hide();
                e.Cancel = true;
                await task;
                this.Close();
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统诊断;
使用系统图;
使用System.Linq;
Net系统;
使用System.Net.Http;
使用System.Net.Http.Header;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows.Forms;
命名空间WindowsFormsApp1
{
公共部分类Form1:Form
{
私有静态HttpClient客户端{get;set;}
私有任务任务{get;set;}
私有CancellationTokenSource cts{get;set;}
私有布尔按钮启动停止状态{get;set;}
公共表格1()
{
初始化组件();
}
专用异步任务RunLongRunningMethod(CancellationToken CancellationToken)
{
尝试
{
while(true)
{
if(cancellationToken.IsCancellationRequested)
{
cancellationToken.ThrowIfCancellationRequested();
}
//一些CPU限制的工作在这里
//然后调用异步
var success=wait GetUrlAsync(@)https://www.bbc.co.uk/");
Thread.Sleep(2000);//仅模拟阻塞
}
}
捕获(操作取消异常)
{
//无需登录即可退出。操作已被用户取消。
}
捕获(例外情况除外)
{
//报告错误
}
}
专用异步任务GetUrlAsync(字符串url)
{
if(客户端==null)
{
client=new-HttpClientHandler(){UseDefaultCredentials=true,AutomaticDecompression=DecompressionMethods.Deflate | DecompressionMethods.GZip});
client.BaseAddress=新Uri(“https://www.bbc.co.uk/");
client.DefaultRequestHeaders.Add(“接受”,“*/*”);
client.DefaultRequestHeaders.AcceptEncoding.Add(新的StringWithQualityHeaderValue(“gzip”);
client.DefaultRequestHeaders.Add(“用户代理”、“Mozilla/5.0(Windows NT 10.0;…)Gecko/20100101 Firefox/62.0”);
client.DefaultRequestHeaders.Connection.Add(“保持活动”);
client.DefaultRequestHeaders.Add(“DNT”,“1”);
}
var response=wait client.GetAsync(url);
var contents=wait response.Content.ReadAsStringAsync();
Debug.WriteLine($“{DateTime.Now}{response.StatusCode}”);
返回true;
}
私有无效按钮启动停止\单击(对象发送者,事件参数e)
{
buttonStartStopState=!buttonStartStopState;
如果(按钮启动停止状态)
{
cts=新的CancellationTokenSource();
//这两者有什么区别
//task=task.Run(()=>RunLongRunningMethod(cts.Token));
//这个呢?
task=runningmethod(cts.Token);
//它总是立即运行
WriteLine($“{DateTime.Now}buttonStartStopState:{buttonStartStopState}”);
}
其他的
{
cts.Cancel();
cts=null;
}
}
私有异步无效Form1\u FormClosing(对象发送方,FormClosingEventArgs e)
{
如果(cts!=null)
{
cts.Cancel();//CancellationTokenSource
cts=null;
}
如果(!task.IsCompleted)
{
//this.Hide();
e、 取消=真;
等待任务;
这个。关闭();
}
}
}
}
运行方法(cts.Token)在同一线程中立即执行操作。这意味着,如果您的代码在UI线程中,它可以阻止您的UI

task=task.Run(()=>RunLongRunningMethod(cts.Token))相反,表示您希望立即执行您的操作。此行对要在线程池上运行的任务进行排队,并返回该工作的任务句柄

通常,我们使用:

Task.Run
当您想要执行长时间运行的代码时,不要等待任务完成。后台计算,即和

task=RunLongRunningMethod
当您想等待任务时,即

await RunLongRunningMethod(token);
//this method DoSomeThing is not executed until your your long-running code finishs
DoSomeThing();
将队列
RunLongRunningMethod
在将来的某个时间由任务池中的一个线程执行。下一行代码将立即执行

鉴于

RunLongRunningMethod(cts.Token);

将在当前线程上执行代码,并且在完成之前不会运行下一行代码。

仅添加到前面的两个答案中

看起来您正在以STA(单线程单元)模型运行的WinForms中运行,这意味着只有线程处理UI排队消息

因此,当您运行
task=task.run(()=>RunLongRunningMethod(cts.Token))这在线程池线程上执行所有操作,默认情况下,
task=RunLongRunningMethod(cts.Token)将在
Thread.Sleep(2000);//仅模拟阻塞
,因为您的等待调用将在UI调度程序上排队,因为您没有
配置等待(false)

总体而言,不在后台线程上运行意味着:

  • 你的
    线程。睡眠(x)
    task = Task.Run(() => RunLongRunningMethod(cts.Token));
    
    RunLongRunningMethod(cts.Token);