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);