本文将介绍tweakomatichta下载的详细情况,特别是关于tweaknt下载的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于.Net中的弱引用
本文将介绍tweakomatic hta 下载的详细情况,特别是关于tweaknt下载的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于.Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍、atomic,nonatomic,strong,retain,weak,assign...、C#make class static?、c++ atomic atomic_compare_exchange_weak CAS 编程的知识。
本文目录一览:- tweakomatic hta 下载(tweaknt下载)
- .Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍
- atomic,nonatomic,strong,retain,weak,assign...
- C#make class static?
- c++ atomic atomic_compare_exchange_weak CAS 编程
tweakomatic hta 下载(tweaknt下载)
<html>
<head>
<title>Tweakomatic 1.0</title>
<HTA:APPLICATION
ID="objTweakomatic"
APPLICATIONNAME="Tweakomatic"
SCROLL="no"
SINGLEINSTANCE="yes"
WINDOWSTATE="maximize"
>
</head>
<style>
BODY
{
background-color: buttonface;
font-family: Helvetica;
font-size: 8pt;
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
margin-bottom: 10px;
}
.button
{
font-family: Helvetica;
font-size: 8pt;
}
textarea
{
font-family: arial;
font-size: 8pt;
margin-left: 3px;
}
select
{
font-family: arial;
font-size: 8pt;
width: 450px;
margin-left: 0px;
}
td
{
font-family: arial;
font-size: 10pt;
}
</style>
<SCRIPT LANGUAGE="VBScript">
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adUseClient = 3
DefaultComputer = "."
MasterFile = ""
RetrievalFile = ""
StartHelp = "To begin, select a manageable component, and then select a category of tasks. When you do so, a set of tasks will be displayed in the Task Area. Click a task and two scripts will automatically be created: one for configuring information, the other for retrieving information."
Help2 = "Select a category from the list of categories. When you do so, a set of tasks will be displayed in the Task Area. Click a task and two scripts will automatically be created: one for configuring information, the other for retrieving information."
Help3 = "Click a task and two scripts will automatically be created: one for configuring information, the other for retrieving information."
Sub Window_Onload
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider= Microsoft.Jet.OLEDB.4.0; Data Source=tweakomatic.mdb"
Set objRecordset = CreateObject("ADODB.Recordset")
objRecordset.CursorLocation = adUseClient
objRecordset.Open "SELECT DISTINCT Tweaks.Component FROM Tweaks ORDER BY Tweaks.Component" , objConnection, adOpenStatic, adLockOptimistic
objRecordSet.MoveFirst
strHTML = "<select width: 460'' onChange=""GetCategoryInfo()"" name=ComponentList>"
strHTML = strHTML & "<option value= " & chr(34) & chr(34) & ">"
Do Until objRecordSet.EOF
strHTML = strHTML & "<option value= " & chr(34) & _
objRecordSet.Fields.Item("Component") & chr(34) & _
">" & objRecordSet.Fields.Item("Component")
objRecordSet.MoveNext
Loop
strHTML = strHTML & "</select>"
ComponentArea.InnerHTML = strHTML
run_button.disabled = True
run_button2.disabled = True
save_button.disabled = True
save_button2.disabled = True
change_button.disabled = True
Master_button.disabled = True
Master_button2.disabled = True
show_button.disabled = True
show_button2.disabled = True
HelpArea.InnerHTML = StartHelp
End Sub
Sub Window_OnUnload
On Error Resume Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile "temp_script.sm"
Set objFSO = Nothing
self.Close()
End Sub
Sub GetCategoryInfo()
On Error Resume Next
FilterValue = ComponentList.Value
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider= Microsoft.Jet.OLEDB.4.0; Data Source=tweakomatic.mdb"
Set objRecordset = CreateObject("ADODB.Recordset")
objRecordset.CursorLocation = adUseClient
objRecordset.Open "SELECT DISTINCT Tweaks.Category FROM Tweaks Where Component = ''" & FilterValue & "''ORDER BY Tweaks.Category" , objConnection, adOpenStatic, adLockOptimistic
objRecordSet.MoveFirst
CategoryArea.InnerHTML = ""
strHTML = "<select width: 460'' onChange=""GetTaskInfo"" name=CategoryList>"
strHTML = strHTML & "<option value= " & chr(34) & chr(34) & ">"
Do Until objRecordSet.EOF
strHTML = strHTML & "<option value= " & chr(34) &_
objRecordSet.Fields.Item("Category") & chr(34) &_
">" & objRecordSet.Fields.Item("Category")
objRecordSet.MoveNext
Loop
strHTML = strHTML & "</select>"
CategoryArea.InnerHTML = strHTML
TaskArea.InnerHTML = "<select size=''15'' name=''D2''>"
HelpArea.InnerHTML= Help2
ScriptArea.Value = ""
RetrievalArea.Value = ""
run_button.disabled = True
run_button2.disabled = True
save_button.disabled = True
save_button2.disabled = True
change_button.disabled = True
Master_button.disabled = True
Master_button2.disabled = True
objRecordSet.Close
objConnection.Close
End Sub
Sub GetTaskInfo()
On Error Resume Next
FilterValue = ComponentList.Value
FilterValue2 = CategoryList.Value
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider= Microsoft.Jet.OLEDB.4.0; Data Source=tweakomatic.mdb"
Set objRecordset = CreateObject("ADODB.Recordset")
objRecordset.CursorLocation = adUseClient
objRecordset.Open "SELECT DISTINCT Tweaks.Task FROM Tweaks Where Component = ''" & FilterValue & "'' AND Category = ''" & FilterValue2 & "''ORDER BY Tweaks.Task" , objConnection, adOpenStatic, adLockOptimistic
objRecordSet.MoveFirst
TaskArea.InnerHTML = ""
strHTML = "<select size = ''15'' width: 460'' onChange=""GetHelpText()"" name=TaskList>"
Do Until objRecordSet.EOF
strHTML = strHTML & "<option value= " & chr(34) &_
objRecordSet.Fields.Item("Task") & chr(34) &_
">" & objRecordSet.Fields.Item("Task")
objRecordSet.MoveNext
Loop
strHTML = strHTML & "</select>"
TaskArea.InnerHTML = strHTML
HelpArea.InnerHTML= Help3
ScriptArea.Value = ""
RetrievalArea.Value = ""
run_button.disabled = True
run_button2.disabled = True
save_button.disabled = True
save_button2.disabled = True
change_button.disabled = True
Master_button.disabled = True
Master_button2.disabled = True
objRecordSet.Close
objConnection.Close
End Sub
Sub GetHelpText()
FilterValue = TaskList.Value
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider= Microsoft.Jet.OLEDB.4.0; Data Source=tweakomatic.mdb"
Set objRecordset = CreateObject("ADODB.Recordset")
objRecordset.CursorLocation = adUseClient
objRecordset.Open "SELECT * FROM Tweaks WHERE Task = ''" & FilterValue & "'' ORDER BY Tweaks.Task" , objConnection, adOpenStatic, adLockOptimistic
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
strHTML = objRecordSet.Fields.Item("Help")
strText2 = "On Error Resume Next" & vbCrLf
strLocation = objRecordSet.Fields.Item("RegistryLocation")
If StrLocation = "HKEY_CURRENT_USER" Then
strText = "HKEY_CURRENT_USER = &H80000001" & VbCrLf
strText2 = strText2 & "HKEY_CURRENT_USER = &H80000001" & VbCrLf
strText = strText & "strComputer = " & chr(34) & DefaultComputer & chr(34) & VbCrLf
strText2 = strText2 & "strComputer = " & chr(34) & DefaultComputer & chr(34) & VbCrLf
strText = strText & "Set objReg = GetObject(" & chr(34) & "winmgmts:\\" & chr(34)
strText2 = strText2 & "Set objReg = GetObject(" & chr(34) & "winmgmts:\\" & chr(34)
strText = strText & " & strComputer & " & chr(34) & "\root\default:StdRegProv" & chr(34) & ")" & VbCrLf
strText2 = strText2 & " & strComputer & " & chr(34) & "\root\default:StdRegProv" & chr(34) & ")" & VbCrLf
strText = strText & "strKeyPath = " & chr(34) & objRecordSet.Fields.Item("RegKey") & chr(34) & VbCrLf
strText2 = strtext2 & "strKeyPath = " & chr(34) & objRecordSet.Fields.Item("RegKey") & chr(34) & VbCrLf
strText = strText & "objReg.CreateKey " & strLocation & ", strKeyPath" & VbCrLf
strText = strText & "ValueName = " & chr(34) & objRecordSet.Fields.Item("RegValue") & chr(34) & VbCrLf
strText2 = strText2 & "ValueName = " & chr(34) & objRecordSet.Fields.Item("RegValue") & chr(34) & VbCrLf
Else
strText = strText & "HKEY_LOCAL_MACHINE = &H80000002" & vbCrLf
strText2 = strText2 & "HKEY_LOCAL_MACHINE = &H80000002" & vbCrLf
strText = strText & "strComputer = " & chr(34) & DefaultComputer & chr(34) & VbCrLf
strText2 = strText2 & "strComputer = " & chr(34) & DefaultComputer & chr(34) & VbCrLf
strText = strText & "Set objReg = GetObject(" & chr(34) & "winmgmts:\\" & chr(34)
strText2 = strText2 & "Set objReg = GetObject(" & chr(34) & "winmgmts:\\" & chr(34)
strText = strText & " & strComputer & " & chr(34) & "\root\default:StdRegProv" & chr(34) & ")" & VbCrLf
strText2 = strText2 & " & strComputer & " & chr(34) & "\root\default:StdRegProv" & chr(34) & ")" & VbCrLf
strText = strText & "strKeyPath = " & chr(34) & objRecordSet.Fields.Item("RegKey") & chr(34) & VbCrLf
strText2 = strText2 & "strKeyPath = " & chr(34) & objRecordSet.Fields.Item("RegKey") & chr(34) & VbCrLf
strText = strText & "objReg.CreateKey " & strLocation & ", strKeyPath" & VbCrLf
strText = strText & "ValueName = " & chr(34) & objRecordSet.Fields.Item("RegValue") & chr(34) & VbCrLf
strText2 = strText2 & "ValueName = " & chr(34) & objRecordSet.Fields.Item("RegValue") & chr(34) & VbCrLf
End If
strValueType = objRecordSet.Fields.Item("DataType")
If strValueType = "REG_DWORD" Then
strText = strText & "dwValue = " & objRecordSet.Fields.Item("DefaultValue") & VbCrLf
strText = strText & "objReg.SetDWORDValue HKEY_CURRENT_USER, strKeyPath, ValueName, dwValue" & VbCrLf
strText2 = strText2 & "objReg.GetDWORDValue HKEY_CURRENT_USER, strKeyPath, ValueName, dwValue" & VbCrLf
strEcho = " Wscript.Echo " & chr(34) & FilterValue & ": " & chr(34) & ", dwValue" & vbCrLf
Else
strText = strText & "strValue = " & chr(34) & objRecordSet.Fields.Item("DefaultValue") & chr(34) & VbCrLf
strText = strText & "objReg.SetStringValue HKEY_CURRENT_USER, strKeyPath, ValueName, strValue" & VbCrLf
strText2 = strText2 & " objReg.GetStringValue HKEY_CURRENT_USER, strKeyPath, ValueName, strValue" & VbCrLf
strEcho = " Wscript.Echo " & chr(34) & FilterValue & ": " & chr(34) & ", strValue" & vbCrLf
End If
strText2 = strText2 & "If IsNull(strValue) Then" & VbCrLf
strText2 = strtext2 & " Wscript.Echo " & chr(34) & FilterValue & ": The value is either Null or could not be found in the registry." & chr(34) & VbCrLf
strText2 = strText2 & "Else" & vbCrLf
strText2 = strText2 & strEcho
strText2 = strtext2 & "End If"
objRecordSet.MoveNext
Loop
HelpArea.InnerHTML = strHTML
ScriptArea.Value = strText
RetrievalArea.Value = strText2
run_button.disabled = False
run_button2.disabled = False
save_button.disabled = False
save_button2.disabled = False
change_button.disabled = False
Master_button.disabled = False
Master_button2.disabled = False
End Sub
Sub RunConfigurationScript()
Set objFS = CreateObject("Scripting.FileSystemObject")
strTmpName = "temp_script.sm"
Set objScript = objFS.CreateTextFile(strTmpName)
objScript.Write ScriptArea.Value
objScript.Close
Set objShell = CreateObject("WScript.Shell")
strCmdLine = "wscript.exe //E:VBScript " & strTmpName
objShell.Run strCmdLine
strAction = "Configured value for " & TaskList.Value
ActionArea.InnerHTML = strAction
End Sub
Sub RunRetrievalScript()
Set objFS = CreateObject("Scripting.FileSystemObject")
strTmpName = "temp_script.sm"
Set objScript = objFS.CreateTextFile(strTmpName)
objScript.Write RetrievalArea.Value
objScript.Close
Set objShell = CreateObject("WScript.Shell")
strCmdLine = "wscript.exe //E:VBScript " & strTmpName
objShell.Run strCmdLine
strAction = "Retrieved value for " & TaskList.Value
ActionArea.InnerHTML = strAction
End Sub
Sub SaveConfigurationScript()
Set objFSO = CreateObject("Scripting.FileSystemObject")
strSaveFileName = InputBox("Please enter the complete path where you want to save your script (for example, C:\Scripts\MyScript.vbs).")
If strSaveFileName = "" Then
Exit Sub
End If
Set objFile = objFSO.CreateTextFile(strSaveFileName)
objFile.WriteLine ScriptArea.Value
objFile.Close
strAction = "Saved " & TaskList.Value & " to " & strSaveFileName
ActionArea.InnerHTML = strAction
End Sub
Sub SaveRetrievalScript()
Set objFSO = CreateObject("Scripting.FileSystemObject")
strSaveFileName = InputBox("Please enter the complete path where you want to save your script (for example, C:\Scripts\MyScript.vbs).")
If strSaveFileName = "" Then
Exit Sub
End If
Set objFile = objFSO.CreateTextFile(strSaveFileName)
objFile.WriteLine RetrievalArea.Value
objFile.Close
strAction = "Saved " & TaskList.Value & " to " & strSaveFileName
ActionArea.InnerHTML = strAction
End Sub
Sub ChangeValue()
strCurrent = ScriptArea.Value
NewValue = InputBox("Please enter the new value: ")
If NewValue = "" Then
Exit Sub
End If
ScriptType = Split(strCurrent, vbCrLf, -1)
If Left(ScriptType(6),2) = "dw" Then
If Not IsNumeric(NewValue) Then
Msgbox "You must enter a number when configuring DWORD registry values."
Exit Sub
End If
ScriptType(6) = "dwValue = " & NewValue
Else
ScriptType(6) = "strValue = " & chr(34) & NewValue & chr(34)
End If
strReplace = Join(ScriptType, vbcrlf)
ScriptArea.Value = strReplace
strAction = "Changed value for " & TaskList.Value & " to " & NewValue
ActionArea.InnerHTML = strAction
End Sub
Sub ChangeMasterFile()
If MasterFile = "" Then
strCurrentFile = "Currently you do not have an master script. "
Else
strCurrentFile = "Your current master script is " & MasterFile & ". "
End If
strMessage = strCurrentFile & "Please enter the path to the new master script: "
NewValue = InputBox(strMessage)
If NewValue = "" Then
Exit Sub
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(NewValue) Then
MasterFile = NewValue
show_button.disabled = False
Else
CreateFile = Msgbox("This file does not exist. Would you like to create it",4)
If CreateFile = vbYes Then
objFSO.CreateTextFile(NewValue)
MasterFile = NewValue
show_button.disabled = False
End If
End If
strAction = "Changed name of master script to " & NewValue
ActionArea.InnerHTML = strAction
End Sub
Sub ChangeRetrievalFile()
If RetrievalFile = "" Then
strCurrentFile = "Currently you do not have a retrieval master script. "
Else
strCurrentFile = "You current retrieval master script is " & RetrievalFile & ". "
End If
strMessage = strCurrentFile & "Please enter the path to the new retrieval master script: "
NewValue = InputBox(strMessage)
If NewValue = "" Then
Exit Sub
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(NewValue) Then
RetrievalFile = NewValue
show_button2.disabled = False
Else
CreateFile = Msgbox("This file does not exist. Would you like to create it",4)
If CreateFile = vbYes Then
objFSO.CreateTextFile(NewValue)
RetrievalFile = NewValue
show_button2.disabled = False
End If
End If
strAction = "Changed name of retrieval master script to " & NewValue
ActionArea.InnerHTML = strAction
End Sub
Sub SetComputerName()
strMessage = "Curently your scripts are using " & DefaultComputer & " as the default computer name. Please enter the new computer name. To run the script against the local computer, simply type a period (.) for the computer name: "
NewValue = InputBox(strMessage)
If NewValue = "" Then
Exit Sub
End If
DefaultComputer = NewValue
strAction = "Changed default computer name to " & NewValue
ActionArea.InnerHTML = strAction
End Sub
Sub MasterConfigurationScript()
Set objFSO = CreateObject("Scripting.FileSystemObject")
If MasterFile = "" Then
strCurrentFile = "Currently you do not have a master script. "
strMessage = strCurrentFile & "Please enter the path to the new master script: "
NewValue = InputBox(strMessage)
If NewValue = "" Then
Exit Sub
End If
If objFSO.FileExists(NewValue) Then
MasterFile = NewValue
show_button.disabled = False
Else
CreateFile = Msgbox("This file does not exist. Would you like to create it",4)
If CreateFile = vbYes Then
objFSO.CreateTextFile(NewValue)
MasterFile = NewValue
show_button.disabled = False
Else
Exit Sub
End If
End If
End If
Set objFile = objFSO.OpenTextFile(MasterFile, 8)
objFile.WriteLine Chr(39) & " " & TaskList.Value
objFile.WriteLine ScriptArea.Value
objFile.WriteLine vbCrLf & vbCrLf
objFile.Close
strAction = "Appended " & TaskList.Value & " to " & MasterFile
ActionArea.InnerHTML = strAction
End Sub
Sub MasterRetrievalScript()
Set objFSO = CreateObject("Scripting.FileSystemObject")
If RetrievalFile = "" Then
strCurrentFile = "Currently you do not have a retrieval master script. "
strMessage = strCurrentFile & "Please enter the path to the new master script: "
NewValue = InputBox(strMessage)
If NewValue = "" Then
Exit Sub
End If
If objFSO.FileExists(NewValue) Then
RetrievalFile = NewValue
show_button2.disabled = False
Else
CreateFile = Msgbox("This file does not exist. Would you like to create it",4)
If CreateFile = vbYes Then
objFSO.CreateTextFile(NewValue)
RetrievalFile = NewValue
show_button2.disabled = False
Else
Exit Sub
End If
End If
End If
Set objFile = objFSO.OpenTextFile(RetrievalFile, 8)
objFile.WriteLine Chr(39) & " " & TaskList.Value
objFile.WriteLine RetrievalArea.Value
objFile.WriteLine vbCrLf & vbCrLf
objFile.Close
strAction = "Appended " & TaskList.Value & " to " & RetrievalFile
ActionArea.InnerHTML = strAction
End Sub
Sub ShowConfigurationScript()
Set objShell = CreateObject("WScript.Shell")
strCmdLine = "notepad.exe " & MasterFile
objShell.Run strCmdLine
strAction = "Opened file " & MasterFile & " in Notepad"
ActionArea.InnerHTML = strAction
End Sub
Sub ShowRetrievalScript()
Set objShell = CreateObject("WScript.Shell")
strCmdLine = "notepad.exe " & RetrievalFile
objShell.Run strCmdLine
strAction = "Opened file " & RetrievalFile & " in Notepad"
ActionArea.InnerHTML = strAction
End Sub
</SCRIPT>
<body>
<BR>
<table border="0" cellspacing="1" width="100%" id="AutoNumber1">
<tr>
<td width = "50%"><b> Select a manageable component from this list</b>
</td>
<td width = "50%"><b> Select a task category from this list</b>
</td>
</tr>
<tr>
<td width="50%">
<span id="ComponentArea"></span>
</td>
<td width="50%"><span id="CategoryArea"><select size="1" name="D1"></select></span></td>
</tr>
</table>
<BR>
<table border="0" cellspacing="1" width="100%" id="AutoNumber2">
<tr>
<td width = "50%"><b> Select an individual task from this list</b>
</td>
<td width = "50%"><b>Task description</b>
</td>
</tr>
<tr>
<td width="50%"><span id="TaskArea"><select size="15" name="D2"></span></td>
<td width="50%" valign="top"><font color="navy"><span id="HelpArea"></span></font></td>
</tr>
</table>
<BR>
<table border="0" cellspacing="1" width="100%" id="AutoNumber3">
<tr>
<td width = "50%"><b> Script for carrying out this task</b>
</td>
<td width = "50%"><b> Script for retrieving the current task setting</b>
</td>
</tr>
<tr>
<td width="50%">
<textarea rows="12" name="ScriptArea" cols="90"></textarea></td>
<td width="50%">
<textarea rows="12" name="RetrievalArea" cols="90"></textarea></td>
</tr>
</table>
<BR>
<table border="0" cellspacing="1" width="100%" id="AutoNumber2">
<tr>
<td width="50%"><input id=runbutton type="button" value="Run Script" name="run_button" onClick="RunConfigurationScript()"><input id=runbutton type="button" value="Save Script" name="save_button" onClick="SaveConfigurationScript()"><input id=runbutton type="button" value="Change Value" name="change_button" onClick="ChangeValue()"><input id=runbutton type="button" value="Master Script" name="Master_button" onClick="MasterConfigurationScript()"><input id=runbutton type="button" value="ShowScript" name="show_button" onClick="ShowConfigurationScript()"></td>
<td width="50%"><input id=runbutton type="button" value="Run Script" name="run_button2" onClick="RunRetrievalScript()"><input id=runbutton type="button" value="Save Script" name="save_button2" onClick="SaveRetrievalScript()"><input id=runbutton type="button" value="Master Script" name="Master_button2" onClick="MasterRetrievalScript()"><input id=runbutton type="button" value="ShowScript" name="show_button2" onClick="ShowRetrievalScript()"></td>
</tr>
</table>
<BR>
<table border="0" cellspacing="1" width="100%" id="AutoNumber2">
<tr>
<td width="100%"> <br><b>Tweakomatic Options</b> <input id=runbutton type="button" value="Set Computer Name" name="computer_name" onClick="SetComputerName()"><input id=runbutton type="button" value="Set Configuration Master Script" name="set_Master_file" onClick="ChangeMasterFile()"><input id=runbutton type="button" value="Set Retrieval Master Script" name="set_retrieval_button" onClick="ChangeRetrievalFile()"></td>
</tr>
<tr>
<td width="100%"> <br><b>Last Action: </b><span id="ActionArea"></span></td>
</tr>
</table>
</body>
</html>

.Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍
有的时候,我们需要给某些数据添加一些附加信息,一种常用的做法是使用一个Dictionary在填充这些附加信息如:
var data = new Data(); var tag = new Tag(); var dictionary = new Dictionary<Data, Tag>(); dictionary[data] = tag;
这么做本身没有什么问题,但是却又一个不小的隐患,那就是在dictionary中保存着了data和tag的引用。当data不再使用的时候,需要将其从dictionary中移除,否则data和tag得不到释放。我们可以用如下代码说明这个问题:(注意,由于Debug模式有时会影响GC,本文代码需行在Release模式下)
class Tag { public Tag() { Console.WriteLine("Create Tag"); } ~Tag() { Console.WriteLine("Release Tag"); } } class Data { public Data() { Console.WriteLine("Create Data"); } ~Data() { Console.WriteLine("Release Data"); } } static void Main(string[] args) { var data = new Data(); var tag = new Tag(); var dictionary = new Dictionary<Data, Tag>(); dictionary[data] = tag; data = null; GC.Collect(); Console.WriteLine("After GC"); Console.ReadLine(); Console.WriteLine(dictionary); }
从运行结果中可以看出,只有创建的输出,而没有释放的输出。这个就属于资源泄漏了。虽然可以通过手动在dictionary中删除data来实现资源的释放,但是这样就要求我们手动管理对象的生命周期了,而这往往不是一个比较容易做到的事情。
究其原因,是由于dictionary中保持着强引用、导致GC不会对其进行回收。找到了这个原因后,那就有相应的对策了,那就是改用弱引用来建立关联,这样数据就会被GC释放了。这种观念关系我们通常称为弱字典——WeakDictionary。弱字典也是保存着Key和Value的键值对,它满足如下需求:
字典中保存着Key的弱引用,即使不释放Key值,也可以被GC回收。
字典中保存的Value的强引用,Key没有被GC回收前,Value不会被GC回收。
当Key被GC回收时,关联关系从字典中移除,Value也能被GC回收。
知道了需求后,接下来就可以对Dictionary进行简单的封装,将其改造成弱字典了。
static void Main(string[] args) { var data = new Data(); var tag = new Tag(); var dictionary = new Dictionary<WeakReference<Data>, Tag>(); var key = new WeakReference<Data>(data); dictionary[key] = tag; data = null; GC.Collect(); Console.WriteLine("After GC"); Console.ReadLine(); Console.WriteLine(dictionary); }
运行这段代码后,我们就会发现,Data数据能释放了,但是并不完善,具体体现在如下方面:
Tag保存的仍然是强引用,得不到释放
Key数据并不是Data类型了,存在一个检索的问题,否则无法CRUD。
对于第一个问题,可以通过一个Timer来定时清理已经释放了的Key来解决;对于第二个问题,则需要在内部通过key来建立Hash表来解决。具体的实现还有点麻烦,也会引入一些新的问题,这里就不继续列举了。
之所以不继续改造下去了,是因为这里我是在造重复轮子,.Net的BCL中本身就已经提供了一个弱字典——ConditionalWeakTable,通过ConditionalWeakTable改造上述代码如下:
static void Main(string[] args) { var data = new Data(); var tag = new Tag(); var dictionary = new ConditionalWeakTable<Data, Tag>(); dictionary.Add(data, tag); data = null; GC.Collect(); Console.WriteLine("After GC"); Console.ReadLine(); Console.WriteLine(dictionary); }
从运行结果来看,GC结束后,Key和Value都被GC回收掉了(再次强调,需要运行在Release版本下)。
这个类放置在System.Runtime.CompilerServices下,也很少见到有书里面介绍到它。这里我就简单的介绍一下其接口吧:
dictionary.Add(data, tag); //添加 dictionary.TryGetValue(data, out tag); //查询 dictionary.Remove(data); //删除
这三个是它比较常见的接口,另外还有两个不大用的接口,这里就不多介绍了。
最后,简单的试了它的性能,基本上和Dictionary差不多,查询效率还是非常高的,内部应该也是一个Hash表。
到此这篇关于.Net弱引用字典WeakDictionary和ConditionalWeakTable的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。
- .NET通过字典给类赋值实现代码
- asp.net 脏字典过滤问题 用正则表达式来过滤脏数据
- C# 泛型字典 Dictionary的使用详解
- C#集合之字典的用法
- C#实现Dictionary字典赋值的方法
- C#字典Dictionary的用法说明(注重性能版)
- C# 如何实现一个基于值相等性比较的字典
- C#创建安全的字典(Dictionary)存储结构
atomic,nonatomic,strong,retain,weak,assign...
atomic:默认是有该属性的,这个属性是为了保证程序在多线程情况,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。
nonatomic:如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。
readwrite:这个属性是默认的情况,会自动为你生成存取器。
readonly:只生成getter不会有setter方法。
readwrite、readonly这两个属性的真正价值,不是提供成员变量访问接口,而是控制成员变量的访问权限。
strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。
weak:弱引用,不决定对象的存亡。即使一个对象被持有无数个弱引用,只要没有强引用指向它,那么还是会被清除。
strong与retain功能相似;weak与assign相似,只是当对象消失后weak会自动把指针变为nil;
assign:默认类型,setter方法直接赋值,不进行任何retain操作,不改变引用计数。一般用来处理基本数据类型。
retain:释放旧的对象(release),将旧对象的值赋给新对象,再令新对象引用计数为1。
copy与mutableCopy已经在上一篇日志中介绍完毕了。
以下是我用代码进行测试的代码:
#warning strong
/******strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。*******/
/******strong是强引用,在该对象(针对存储在堆空间上面的对象来说)创建并分配空间的时候,又对这个对象进行了强引用,该对象的retaiCount加了1,所以下面的测试用例中可以可见初始完之后,它的retainCount就是2。所以用strong的时候,即便整个控制器被释放了,用strong修饰的对象也不会被释放,因为strong会决定该对象一直存在。*******/
-(void)test1
{
/**
* 非容器类
*/
/******字符串是存在数据常量区,系统并没有对其进行引用计数*******/
self.strStrong1=@"123";/******self.strStrong1.retainCount:-1,用NSLOG输出,用po输出会有问题*******/
self.strStrong2=self.strStrong1;/******self.strStrong2.retainCount:-1*******/
self.strStrong1=nil;/******self.strStrong1:nil,self.strStrong2:123,self.strStrong2.retainCount:-1*******/
/******注:self.strStrong1对应的内存空间被强引用了两次,所以即便self.strStrong1被置为nil,对应的内存空间也是没有被释放,因为还有另外一个强引用指向它*******/
/**
* 容器类
*/
NSArray *array1=@[@"1",@"2",@"3"];/******array1.retainCount:1*******/
/******提示:这里我们可以看出,局部变量一开始被创建的时候,他的retainCount是为1的,这是正常的。但是self.arrayStrong1是被strong修饰的,在它初始化的时候就对其进行了一次强引用导致它的retainCount变为2。*******/
self.arrayStrong1=@[@"1",@"2",@"3"];/******self.arrayStrong1.retainCount:2*******/
self.arrayStrong2=self.arrayStrong1;/******self.arrayStrong1.retainCount:3*******/
self.arrayStrong1=nil;
}
#warning strong与retain
/******strong与retain的作用相似,都是对被修饰的对象进行retainCount+1的操作。*******/
-(void)test2
{
self.arrayStrong1=@[@"1",@"2",@"3"];/******self.arrayStrong1.retainCount:2*******/
self.arrayRetain=self.arrayStrong1;/******self.arrayStrong1.retainCount:3*******/
self.arrayStrong1=nil;
/******self.arrayStrong1:(null),self.arrayRetain:(
1,
2,
3
)*******/
NSLog(@"self.arrayStrong1:%@,self.arrayRetain:%@",self.arrayStrong1,self.arrayRetain);
}
#warning retain,weak
/******弱引用,不决定对象的存亡。即使一个对象被持有无数个弱引用,只要没有强引用指向它,那么还是会被清除。*******/
/******如果一个对象没有一个指向该对象的引用(可以理解为强引用),并且该对象不存在于列表中,该对象就会被释放。*******/
-(void)test3
{
self.arrayRetain=@[@"1",@"2",@"3"];
self.arrayWeak=self.arrayRetain;
self.arrayRetain=nil;
/******self.arrayRetain:(null),self.arrayWeak:(null)*******/
NSLog(@"self.arrayRetain:%@,self.arrayWeak:%@",self.arrayRetain,self.arrayWeak);
}
不足之处,欢迎指正。
C#make class static?
class ContentManager : Idisposable { List<int> idlist = new List<int>(); public int Load(string path) { //Load file,give content,gets an id //... int id = LoadFile(myfilecontent); idlist.Add(id); return id; } public void dispose() { //Delete the given content by id,stored in idlist foreach(int id in idlist) { DeleteContent(id); } } }
我想让它成为静态的,因为我只需要一个实例,并且可以在不提供实例的情况下从其他所有类访问该函数.
我可以使其中的每个变量都是静态的,函数是静态的.
但我的问题是这个Idisposable.我不能在静态类中使用接口.我怎么能在最后做一些动作?我的意思是我可以删除该接口,但将函数保留在其中并使用我的主类,当我的主类被释放时,我调用ContentManager.dispose().但是当我忘记在我的主…
你有一个很好的解决方案吗?确保每次程序关闭时都调用dispose?
编辑:我在图形卡中加载数据并返回指针.当我的应用程序关闭时,我需要从显卡中删除内容.为了安全起见,一切都被删除了,我使用了dispose.
解决方法
如果你真的需要实现Idisposable并希望只有一个类的实例,那么使用Singleton模式是一个更好的解决方案吗?
您的课程可能如下所示:
class ContentManager : Idisposable { List<int> idlist = new List<int>(); static ContentManager instance=null; ContentManager() { } public static ContentManager Instance { get { if (instance==null) { instance = new ContentManager(); } return instance; } } public int Load(string path) { //Load file,gets an id //... int id = LoadFile(myfilecontent); idlist.Add(id); return id; } public void dispose() { //Delete the given content by id,stored in idlist foreach (int id in idlist) { DeleteContent(id); } } }
它不是线程安全的,但在您的场景中可能就足够了.
c++ atomic atomic_compare_exchange_weak CAS 编程
概述
在多线程应用中有个很典型的业务就是共同争抢一个某一个资源,比如很典型的秒杀,很多的线程在争夺某一个资源。本文以一个最简单的例子说明,2 万个线程一起争夺一个变量 + 1 的操作。
只使用 atomic
在 https://my.oschina.net/u/3707404/blog/3211668 中,使用 atomic 类型可以避免多线程加锁导致的效率问题。
#include <vector> #include <queue> #include <iostream> #include <boost/thread.hpp> #include <chrono> class Task { public: std::atomic<int> queue; boost::mutex mutex; Task() { queue = 0; } void get() { if (queue == 0) { usleep(1); queue++; } } }; int main(int argc, char **argv) { auto begin = std::chrono::high_resolution_clock::now(); boost::thread_group threads; boost::shared_ptr<Task> task = boost::make_shared<Task>(); for (int i = 0; i < 5000; i++) { threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); } threads.join_all(); std::cout << "current value " << task->queue << " \n"; auto end = std::chrono::high_resolution_clock::now(); std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count() << "ns" << std::endl; return 0; }
输出结果
current value 6
537372675ns
加锁
接下来我们尝试加锁
#include <vector> #include <queue> #include <iostream> #include <boost/thread.hpp> #include <chrono> class Task { public: std::atomic<int> queue; boost::mutex mutex; Task() { queue = 0; } void get() { boost::lock_guard<boost::mutex> lock{mutex}; if (queue == 0) { usleep(1); queue++; } } }; int main(int argc, char **argv) { auto begin = std::chrono::high_resolution_clock::now(); boost::thread_group threads; boost::shared_ptr<Task> task = boost::make_shared<Task>(); for (int i = 0; i < 5000; i++) { threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); } threads.join_all(); std::cout << "current value " << task->queue << " \n"; auto end = std::chrono::high_resolution_clock::now(); std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count() << "ns" << std::endl; return 0; }
current value 1
699948447ns
加锁可以解决资源问题,但是不可避免的导致性能的浪费。
CAS 操作
#include <vector> #include <queue> #include <iostream> #include <boost/thread.hpp> #include <chrono> class Task { public: std::atomic<int> queue; boost::mutex mutex; Task() { queue = 0; } void get() { int n = 0; usleep(1); if (std::atomic_compare_exchange_weak(&queue, &n, n + 1)) { std::cout << "i got the atomic add \n"; } } }; int main(int argc, char **argv) { auto begin = std::chrono::high_resolution_clock::now(); boost::thread_group threads; boost::shared_ptr<Task> task = boost::make_shared<Task>(); for (int i = 0; i < 5000; i++) { threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); threads.create_thread(boost::bind(&Task::get, task)); } threads.join_all(); std::cout << "current value " << task->queue << " \n"; auto end = std::chrono::high_resolution_clock::now(); std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count() << "ns" << std::endl; return 0; }
i got the atomic add
current value 1
484698816ns
可以看到使用 atomic_compare_exchange_weak 机制是性能最好,并同时保证了资源的安全。
总结
atomic_compare_exchange_weak 是一种兼顾性能和资源安全的多线程同步模式,https://en.cppreference.com/w/c/atomic/atomic_compare_exchange
今天关于tweakomatic hta 下载和tweaknt下载的分享就到这里,希望大家有所收获,若想了解更多关于.Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍、atomic,nonatomic,strong,retain,weak,assign...、C#make class static?、c++ atomic atomic_compare_exchange_weak CAS 编程等相关知识,可以在本站进行查询。
本文标签: