我必须重构一个大的C#应用程序,我发现了很多从未使用过的函数.如何检查未使用的代码,以便删除所有未使用的功能?
我想要一个相对无黑客的方式来做这个,任何想法?例如,以下截图不包括半透明窗口:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown
Text = "Opaque Window"
Dim win2 As New Form
win2.Opacity = 0.5
win2.Text = "Tranparent Window"
win2.Show()
win2.Top = Top + 50
win2.Left = Left() + 50
Dim bounds As Rectangle = System.Windows.Forms.Screen.GetBounds(Point.Empty)
Using bmp As Bitmap = New Bitmap(bounds.Width, bounds.Height)
Using g As Graphics = Graphics.FromImage(bmp)
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size)
End Using
bmp.Save("c:\temp\scn.gif")
End Using
Process.Start(New Diagnostics.ProcessStartInfo("c:\temp\scn.gif") With {.UseShellExecute = True})
End Sub
End …Run Code Online (Sandbox Code Playgroud) 我有一个程序可以处理大量数据,并且可以缓存大部分数据,以便在内存中使用后续记录.我缓存的越多,它的工作速度就越快.但如果我缓存太多,繁荣,重新开始,这需要更长的时间!
在异常发生后,我没有成功地尝试做任何事情 - 我无法获得足够的内存来做任何事情.
此外,我尝试分配一个巨大的对象,然后立即取消分配,结果不一致.也许我做错了什么?
无论如何,我所坚持的只是在缓存对象的#上设置一个硬编码限制,从经验来看,它似乎足够低.还有更好的想法?谢谢.
以下代码似乎正在做我想要的:
Loop
Dim memFailPoint As MemoryFailPoint = Nothing
Try
memFailPoint = New MemoryFailPoint( mysize) ''// size of MB of several objects I'm about to add to cache
memFailPoint.Dispose()
Catch ex As InsufficientMemoryException
''// dump the oldest items here
End Try
''// do work
next loop.
Run Code Online (Sandbox Code Playgroud)
我需要测试它是否在这种安排下放慢速度,但我可以看到任务管理器中的黄线看起来像一个非常健康的锯齿模式,具有一致的顶部!
我有一个带有多个GUI线程的winforms应用程序.我希望他们能够访问彼此的线程对象,而无需单独跟踪这些信息.
.NET中是否有一个函数可以提供winforms控件或窗口对象,然后返回线程?或者API中的函数我可以为threadID设置pinv?
(请不要发表评论说我应该采取另一种方式......这也不是关于跨线程窗口操作.)
谢谢!
对于那些因某种原因相信我的斜体文字,祝贺你的人,你被录用了!! 这是问题所在:
"应用程序通过完全锁定而崩溃,即它停止响应.非常间歇性,并试图调试它,似乎永远不会发生."
那怎么办?在用户可以在我们的指导下激活的程序中安装一个选项,从同一应用程序中的另一个GUI线程,在主GUI线程上执行thread.abort,然后我们可以在错误日志中查看调用堆栈.Viola,在不到一天的时间内发现无法调试错误.(现在停止,它与滥用多线程无关:-)
我承认我几乎没有问这个,我做的原因是我可以看到主要表单的对象引用,但是它的线程没有.我给Chris Shain答案a/c这是一个快速的方法,不幸的是当线程挂起时,我将无法进行调用(它也会挂起).稍微挖掘一下,揭示了GetWindowThreadProcessId API调用.但它是一个非托管的线程ID,显然有并发症将其转换为托管线程ID.
所以我咬了一口子,并对主UI线程进行了全局引用.本来会发布它,但尚未写出来.
现在,如果你原谅VB ......
Public GUIThread As Threading.Thread
Sub Main()
'' // Create app main window
ShellForm = New frmShell
'' // Save main GUI Thread for abort routine
GUIThread = Threading.Thread.CurrentThread
If GetSetting("MyApp", "Testing", "CrashDebug", "False") = "True" Then
'' // DO NOT run the pgm. like this normally - with try/catch around
'' // Application.Run - or uncaught errors will kill the whole …Run Code Online (Sandbox Code Playgroud) 我注意到VB.Net对Winform对象的处理非常讨厌.
这已经破坏了我们几个小时的时间.它只会变得更糟,因为我们有更多的VB6程序员用来做这样的事情,并且自动转换的代码从vb6直接带来了构造.
这是一种可接受的做事方式:
Dim FormInstance as New FormClassName
If FormInstance.ShowDialog() = DialogResult.OK then
TheAnswer = FormInstance.TextBox1.Text
EndIf
Run Code Online (Sandbox Code Playgroud)
但是,它允许这样:
If FormClassName.ShowDialog() = DialogResult.OK then
TheAnswer = FormClassName.TextBox1.Text
EndIf
Run Code Online (Sandbox Code Playgroud)
请记住,属性和方法不是共享的.转换应用程序框架并不重要.似乎在幕后,VB实例化了表单的全局副本,并将此语法重新路由到该全局引用.你可以想象这对现代节目造成的破坏!通常开发人员会把它扔进去或者我们会错过从转换中清除一些模糊的代码(是的,我现在正在寻找这个,所以这有帮助).
我可以做的任何设置导致它抛出错误信息,例如Reference to a non-shared member requires an object reference,像它应该的那样?
我选择了jmoreno的答案,因为他指出了我的罪魁祸首:My.Forms.修复它就像把它放在一个模块中一样简单:
Namespace My.MyProject.MyForms
End Namespace
Run Code Online (Sandbox Code Playgroud)
然后你得到我上面提到的确切错误.就像你应该的那样.如果您需要遗留应用程序(一件好事),那么就不要这样做!我认为Gserg可能只是VB抨击(有趣但没有帮助),但他马上提到了这一切,因为我找到了答案,我们再次对vb不再吮吸,除非你不熟悉它.
请注意,如果您使用应用程序框架,则会在application.designer中收到您不想要的错误.修复:
Protected Overrides Sub OnCreateMainForm()
''//was: Me.MainForm = Global.WindowsApplication2.Form1
Me.MainForm = New Form1
End Sub
Run Code Online (Sandbox Code Playgroud)
希望这对任何不良副作用都是如此!
以上是如此简单以至于我不想提出任何其他建议,但是如果你很好奇,那么这些代码的改进就是(1)添加反射以省略必须在你制作的每个表格中进行硬编码,以及(2)自动制作强制执行(在程序启动时只调用一次该子程序).把它放在一个模块中:
Public Sub FixMyForms()
For Each pi As System.Reflection.PropertyInfo In GetType(My.MyProject.MyForms).GetProperties
Dim obj As Object …Run Code Online (Sandbox Code Playgroud) 我有两个解决方案,solution1包含project1,它生成一个源文件,编译成solution2(有project2).您只需构建并运行solution1,然后构建并运行solution2.
我的一些团队成员抱怨这是可用性的,因此,我将两个项目放在一个解决方案中,并将它们设置为运行(多个启动项目).我在project2中放置了一个预构建步骤,等待project1完成运行,因此将使用project1运行时生成的最新代码构建project2.
麻烦的是,它不起作用!Visual Studio构建project1,而项目2正在等待它完成运行(因为那时代码project2需要由project1生成).但Visual Studio显然不会运行任何项目,直到它们全部完成构建,因此"等待project1"使project2不能构建(按设计),但也使project1无法运行(尽管它不必).
有没有办法绕过这个并执行我想要的功能,或代码/解决方法?
在 C# 中,我可以在方法中执行此操作:
var Content = new Dictionary<string, System.Text.StringBuilder>();
Run Code Online (Sandbox Code Playgroud)
在 VB.Net 中我可以用一种方法来做到这一点:
Dim Content = new Dictionary(of string, System.Text.StringBuilder)
Run Code Online (Sandbox Code Playgroud)
然而,在 VB 中,我也可以在定义字段/成员变量时在方法之外执行此操作(注意,在这种情况下,VB 不会推断类型,而是显式获取类型,这是在“选项推断”之前的 VB.Net 中) ):
Dim Content AS new Dictionary(of string, System.Text.StringBuilder)
Run Code Online (Sandbox Code Playgroud)
在 C# 中,我似乎必须这样做:
Dictionary<string, System.Text.StringBuilder> Content = new Dictionary<string, System.Text.StringBuilder>();
Run Code Online (Sandbox Code Playgroud)
请注意,我必须重复该类型两次。
这是一个简单的例子,对于更复杂的情况,它至少会有点烦人。
我不敢相信 VB 中有更紧凑的东西;我在这里错过了什么吗?如何声明成员变量并初始化而不重复类型?
来自 Ron 评论中提到的 Eric Lippert 文档:“...如果我们的目标是删除冗余,那么我宁愿以其他方式删除它。使此合法: private static readonly Dictionary NiceNames = new().. .也就是说,在声明中明确地声明类型,然后让“new”运算符根据分配给的类型聪明地找出它正在构造的类型......”
因此,Eric 提出了一个想法他自己讲述了如何做到这一点 - 实际上这就是 VB 所做的一切。(顺便说一下,罗恩,找到该文档非常好)
我有一个掩码位图(bmpMask),我正在绘制到目标位图(bmpDest).两个位图都有alpha通道,但已经充满了不透明的内容.
我想要做的是在bmpMask上使用GDI +'Draw ...'方法生成透明区域,以便当我在其上绘制bmpMask时bmpDest显示出来.
当然gMask.DrawLine(Pens.Transparent, 0, y, wMax, y)导致bmpMask没有变化,因为GDI +按设计工作,透明时不绘制任何东西.即使使用半透明颜色,也只更新bmpMask像素的r,g,b值.
但我想要做的是发出一个draw方法,它将改变bmpMask的alpha通道,使其在绘制到bmpDest时是透明的.我知道我可以使用SetPixel或更快速的不安全或Marshall替代品来做到这一点,但这会导致更复杂的解决方案.谢谢.
所以在winforms中,每个下拉组合框都有一个向右的小箭头告诉用户它是一个下拉列表,有点像这样:
现在我如何计算像素的宽度?原因是,我正在使用ControlDrawToBitmap,这不会为组合框正确绘制文本,我可以重绘内容,我只是敲了一些箭头(正确绘制).