gpt4 book ai didi

c# - 是否需要定义 Int 变量以从不同的线程访问?

转载 作者:太空宇宙 更新时间:2023-11-03 10:46:27 25 4
gpt4 key购买 nike

我有接收文件 List 并在单独线程中工作的函数:

private static CancellationTokenSource _tokenSource;
private static int _filesInProcess;
private static int _filesFinished;
private IEnumerable<Tuple<int, string>> _indexedSource;

public static int FilesInProcess
{
get { return _filesInProcess; }
set { _filesInProcess = value; }
}

public static int FilesFinished
{
get { return _filesFinished; }
set { _filesFinished = value; }
}

public void DoWork(int parallelThreads)
{
_filesInProcess = 0;
_filesFinished = 0;
_tokenSource = new CancellationTokenSource();
var token = _tokenSource.Token;
Task.Factory.StartNew(() =>
{
try
{
Parallel.ForEach(_indexedSource,
new ParallelOptions
{
MaxDegreeOfParallelism = parallelThreads //limit number of parallel threads
},
file =>
{
if (token.IsCancellationRequested)
return;
//do work...
});
}
catch (Exception)
{ }

}, _tokenSource.Token).ContinueWith(
t =>
{
//finish...
}
, TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread
);
}

如您所见,我有 2 个变量,指示有多少文件已经开始以及有多少已完成(_filesInProcess 和 _filesFinished)

我的问题:

  1. 我是否需要将这些变量设置为从不同的线程访问,或者这样可以吗?
  2. 在功能完成并且我的所有文件都播放完并且我想开始一个新的文件后,可以选择从任务类执行还是简单的 while 会为我完成工作?

最佳答案

1 Do I need to set these variables to be accessed from different threads or this is OK ?

是的,你知道。几件事。您应该在计数器的声明中添加一个 volatile 关键字,例如

private static volatile int _filesInProcess;

这确保所有读取实际上读取当前值,这与读取兑现值形成对比。如果要修改和读取计数器,应考虑使用 Interlocked 类,例如 Interlocker.Increment

2 After the function finished and all my files finished to play and i want to start a new one, there is option to do from Task class or simple while will do the work for me ?

不确定这个,胡乱猜测(不清楚您需要什么)。您可以像以前一样使用任务延续(最后一段代码)。作为替代方案,Task.Factory.StartNew 返回一个任务,您可以将其保存到局部变量并根据需要启动它(比如单击按钮)。您可能需要稍微更新代码,因为 Task.Factory.StartNew 会立即启动任务,而您可能只想创建一个任务并在某个事件上运行它。

根据你的评论,你可以做类似的事情(用记事本编码)

private Task _task; // have a local task variable

// move your work here, effectively what you have in Task.Factory.StartNew(...)
public void SetupWork()
{
task = new Task (/*your work here*/);
// see, I don't start this task here
// ...
}

// Call this when you need to start/restart work
public void RunWork()
{
task.Run();
}

关于c# - 是否需要定义 Int 变量以从不同的线程访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23194156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com