Skip to content

Instantly share code, notes, and snippets.

@stilllisisi
Created March 11, 2020 08:16
Show Gist options
  • Save stilllisisi/cff06f539059187464c90635cfbadbbf to your computer and use it in GitHub Desktop.
Save stilllisisi/cff06f539059187464c90635cfbadbbf to your computer and use it in GitHub Desktop.
【游戏-unity】Unity编辑器下多线程处理文件
//主线程阻塞掉,直到信号通知继续执行下面的操作。另外,保证多线程的数量跟处理器数量一致,最大化使用多线程。
#region 多线程执行
private class JobFileTextSearchReplace
{
private string m_Path;
private List<string> m_Patterns;
private string m_ReplaceStr;
private bool[] m_SearchRet;
public ManualResetEvent doneEvent;
public string exception;
public JobFileTextSearchReplace(string path, List<string> patterns, string replaceStr, bool[] searchRet)
{
m_Path = path;
m_Patterns = patterns;
m_ReplaceStr = replaceStr;
m_SearchRet = searchRet;
doneEvent = new ManualResetEvent(false);
}
public void ThreadPoolCallback(System.Object threadContext)
{
try
{
string text = File.ReadAllText(m_Path);
///
}
catch (Exception ex)
{
exception = m_Path + "\n" + ex.Message;
}
doneEvent.Set();
}
}
protected void ThreadDoFilesTextSearchReplace(List<string> fileList, List<string> patterns, string replaceStr, bool[][] searchRetList)
{
List<JobFileTextSearchReplace> jobList = new List<JobFileTextSearchReplace>();
List<ManualResetEvent> eventList = new List<ManualResetEvent>();
int numFiles = fileList.Count;
int numFinished = 0;
AssetDanshariUtility.DisplayThreadProgressBar(numFiles, numFinished);
int timeout = 600000; // 10 分钟超时
for (var i = 0; i < fileList.Count; i++)
{
JobFileTextSearchReplace job = new JobFileTextSearchReplace(fileList[i], patterns, replaceStr, searchRetList[i]);
jobList.Add(job);
eventList.Add(job.doneEvent);
ThreadPool.QueueUserWorkItem(job.ThreadPoolCallback);
if (eventList.Count >= Environment.ProcessorCount)
{
WaitForDoFile(eventList, timeout);
AssetDanshariUtility.DisplayThreadProgressBar(numFiles, numFinished);
numFinished++;
}
}
while (eventList.Count > 0)
{
WaitForDoFile(eventList, timeout);
AssetDanshariUtility.DisplayThreadProgressBar(numFiles, numFinished);
numFinished++;
}
foreach (var job in jobList)
{
if (!string.IsNullOrEmpty(job.exception))
{
Debug.LogError(job.exception);
}
}
}
private void WaitForDoFile(List<ManualResetEvent> events, int timeout)
{
int finished = WaitHandle.WaitAny(events.ToArray(), timeout);
if (finished == WaitHandle.WaitTimeout)
{
// 超时
}
events.RemoveAt(finished);
}
#endregion
@stilllisisi
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment