在C#中,线程优先级是指操作系统调度线程执行的顺序。每个线程都有一个优先级,这决定了它与其他线程相比获取CPU时间的优先权。C#利用System.Threading.ThreadPriority枚举来设置线程的优先级。
ThreadPriority枚举包含以下值:
Lowest:最低优先级。BelowNormal:低于正常优先级。Normal:正常优先级。AboveNormal:高于正常优先级。Highest:最高优先级。下面的示例演示了如何创建两个线程,并为它们设置不同的优先级。
C#using System;
using System.Threading;
class Program
{
static void Main()
{
Thread thread1 = new Thread(Thread1Function);
Thread thread2 = new Thread(Thread2Function);
// 设置线程优先级
thread1.Priority = ThreadPriority.Lowest;
thread2.Priority = ThreadPriority.Highest;
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine("主线程结束。");
}
static void Thread1Function()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread1正在执行...");
Thread.Sleep(1000);
}
}
static void Thread2Function()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread2正在执行...");
Thread.Sleep(1000);
}
}
}
在.NET中,AutoResetEvent和ManualResetEvent是两种常用的同步原语,它们用于在多线程环境中实现线程之间的同步。尽管它们都是从EventWaitHandle派生的,但它们在行为上有所不同。在Windows窗体(WinForms)应用程序中,这两种事件可以帮助我们在UI线程和工作线程之间同步操作,以确保线程安全和数据的一致性。
AutoResetEvent是一个同步原语,当它被设置为信号状态时,允许一个等待的线程继续执行。一旦释放了一个等待的线程,AutoResetEvent会自动回到非信号状态,这意味着它会自动重置。
假设我们在WinForms应用程序中有一个需要执行长时间运行操作的按钮。我们可以使用AutoResetEvent来确保在操作完成之前,用户不能再次点击该按钮。
C#private AutoResetEvent autoResetEvent = new AutoResetEvent(true);
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
if (autoResetEvent.WaitOne(0))
{
Task.Run(() =>
{
// 执行长时间运行的操作
Thread.Sleep(5000); // 假设操作耗时5秒
this.Invoke(() =>
{
lblTitle.Text = DateTime.Now.ToString();
});
// 操作完成,设置事件状态,允许再次点击按钮
autoResetEvent.Set();
});
}
else
{
MessageBox.Show("操作正在进行中,请稍候...");
}
}
在 C# 中,CancellationTokenSource 是一个用于创建和管理 CancellationToken(取消标记)的类。它提供了一种简单的方式来请求取消异步或多线程操作。
看一下Cancel的顺序
C#static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken cancellationToken = cts.Token;
cancellationToken.Register(() =>
{
Console.WriteLine("Cancel1...");
});
cancellationToken.Register(() =>
{
Console.WriteLine("Cancel2...");
});
cancellationToken.Register(state =>
{
Console.WriteLine("Cancel3..." + state.ToString());
}, "OK");
Console.WriteLine("开始...");
cts.Cancel();
}
在C#中,可以使用Factory.StartNew()方法来调用一个对象的实例。Factory.StartNew()方法的用法很简单,它接受一个参数,即需要创建的对象类型,并返回一个实例。 除了直接使用Factory.StartNew()方法创建对象之外,还可以通过继承或重写抽象类或接口的方法来创建对象。这样,当需要创建一个特定类型的对象时,可以使用Factory.StartNew()方法调用对应的抽象类或接口,并在方法中指定对象的属性和方法。
.NET 提供了一个类方便用来发出操作取消的信号,这个类就是CancellationToken,它的好处在于它可以在任意数量的线程之间、线程池任务之间、Task之间传递信号,并且所需的代码很简单。通常用于下载超时中断、用户取消任务等情况。
CancellationToken 通常搭配 CancellationTokenSource 使用,后者是前者的一个管理类,使用 CancellationTokenSource 的 Token 属性,可以获取CancellationToken,并控制信号的发送。这两个类都属于命名空间 System.Threading
在异步编程中,只需将 Token 作为一个参数传入异步方法中。在异步方法外便能通过 CancellationTokenSource.Cancel 方法发出取消信号或者 CancelAfter 方法在一段时间后发出取消信号,这会改变 Token 的 isCancellationRequested 属性。在异步方法内,通过这个属性获取取消信号,并作出对应的处理操作。
一个例子
