只是想知道.NET是否提供了一种干净的方法来执行此操作:
int64 x = 1000000;
string y = null;
if (x / 1024 == 0) {
y = x + " bytes";
}
else if (x / (1024 * 1024) == 0) {
y = string.Format("{0:n1} KB", x / 1024f);
}
Run Code Online (Sandbox Code Playgroud)
等等...
如果我对ThreadPool工作方式的理解是正确的,那么其目的之一就是限制可以在给定时间创建的进程中的工作线程数.例如,如果将MaxThreads设置为5,然后将QueueUserWorkItem调用30次,则将向ThreadPool发出30个请求,但这些请求中只有5个将由新线程提供服务,而其他25个请求将被添加到队列中并且随着先前的请求完成并且现有线程变得可用,一次服务一个.
但是,在下面的代码中,对Thread.Sleep(-1)的调用保证DoSomething()方法永远不会返回,这意味着当前线程永远不会对后续请求可用.
但是我对ThreadPool工作方式的理解不正确,因为如果它是正确的,下面的代码只打印数字0-4而不是0-29.
有人可以解释ThreadPool如何工作以及为什么下面的代码没有做我认为它应该做的事情?
static void DoSomething(object n)
{
Console.WriteLine(n);
Thread.Sleep(-1);
}
static void Main(string[] args)
{
ThreadPool.SetMaxThreads(5, 5);
for (int x = 0; x < 30; x++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), x);
}
Console.Read();
}
Run Code Online (Sandbox Code Playgroud) 在C#中,静态类是一个类,除了不支持继承之外,还可以具有"普通"类除了实例成员之外的任何类型的成员.
不太确定静态类在java中是如何工作的,但基于我看到的有限数量的java代码,我很清楚它们的工作方式并不完全相同.
有人可以列举一下差异吗?
在比较字符串时,我宁愿不依赖实例方法,以免调用该方法的字符串为空.在.NET中,我只使用静态String.Compare(string,string,bool)方法.java提供了类似的内置"null-safe"字符串比较实用程序,还是我必须实现自己的?
此应用程序显示带有文本框的表单,用户应在其中输入用于解密文档的密码.
我的代码看起来像这样:
string password = passwordTextBox.Text;
...
DecryptDocument(password);
Run Code Online (Sandbox Code Playgroud)
但我被告知,从技术上讲,这是一个安全漏洞,因为即使应用程序关闭后,代表密码的数据也可能保留在内存中.
我试图使用System.Security.SecureString类,但现在我正在处理指向CoTaskMem的指针,这似乎使问题变得更糟:
SecureString password = new SecureString();
foreach(char i in passwordTextBox.Text.ToCharArray())
password.AppendChar(i);
IntPtr ptr = Marshal.SecureStringToCoTaskMemAnsi(password);
int length = password.Length;
byte[] bytes = new byte[length];
Marshal.Copy(ptr, bytes, 0, length);
DecryptDocument(Encoding.Default.GetString(bytes));
Marshal.FreeCoTaskMem(ptr);
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它看起来并不像我使应用程序更安全,因为迟早我将不得不接受输入(passwordTextBox.Text)并将其转换为我可以传递给DecryptDocument()的字符串功能.
有没有办法解决这个问题,还是应该处理这个安全漏洞?
Windows无法使32位进程加载64位dll,因此我尝试使用远程处理以允许32位进程与64位进程交互.
这就是问题所在:虽然两个应用程序位于同一台机器上,但一个是32位,另一个是64位,它们必须是这样的:32位或64位都会破坏这些应用程序构建在顶层的所有内容的.
我正在使用.NET的System.Runtime.Remoting.RemotingConfiguration类并调用其Configure()方法并将引用传递给App.config文件,该文件引用我将通过远程处理访问的MarshalByRefObject类.
我得到它的工作,但只有长,Client,Host,MarshalByRefObject类是32位或64位.如果我把它们混合起来这将无效:我最终会遇到BadImageFormatException:
无法加载文件或程序集"MyRemotingObject"或其依赖项之一.尝试加载格式不正确的程序.
只要我将这两个应用程序设置为32位或64位,异常就会消失,但同样,其中一个必须是32位,另一个必须是64位.
有人能告诉我如何在32位.NET应用程序和.64位.NET应用程序之间启用进程间通信吗?
目标是以编程方式启动Windows窗体,获取其句柄,并使用Win Api的SendMessage()函数将信息发送到其wndProc()函数.
我得到了SendMessage()部分,但现在的问题是在进程启动后获取表单的句柄.
我的第一个猜测是Process'MainWindowHandle属性会让我得到我正在寻找的句柄,但是在我启动进程之后MainWindowHandle保持等于0并且以下代码没有显示我刚开始的进程的句柄:
foreach (Process p in Process.GetProcesses())
{
Console.WriteLine(p.MainWindowHandle);
}
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我如何做到这一点,以及它是否可以实际完成?
假设 A、B、C 派生自 AbstractBaseClass,并且它们都是同一个 java 项目的一部分,是以下形式的包结构...
package com.whatever.###
AbstractBaseClass.java
package com.whatever.###.###
A.java
B.java
C.java
Run Code Online (Sandbox Code Playgroud)
...通常优于以下形式的封装结构...
package com.whatever.###.###
AbstractBaseClass.java
A.java
B.java
C.java
Run Code Online (Sandbox Code Playgroud)
?
...或者很少有人会关心?
我认为下面的代码会让所有10个线程一次运行两个,然后在Release()
调用10次后打印"done" .但事情并非如此:
int count = 0;
Semaphore s = new Semaphore(2, 2);
for (int x = 0; x < 10; x++)
{
Thread t = new Thread(new ThreadStart(delegate()
{
s.WaitOne();
Thread.Sleep(1000);
Interlocked.Increment(ref count);
s.Release();
}));
t.Start(x);
}
WaitHandle.WaitAll(new WaitHandle[] { s });
Console.WriteLine("done: {0}", count);
Run Code Online (Sandbox Code Playgroud)
输出:
done: 6
Run Code Online (Sandbox Code Playgroud)
如果实现我正在寻找的功能的唯一方法是传递一个EventWaitHandle
到每个线程,然后WaitAll()
在那些数组上做一个EventWaitHandles
,那么WaitAll()
在一个只有一个信号量的数组上做什么是什么意思?换句话说,等待线程何时解除阻塞?
如果你有这个代码:
"......".Split(new String[]{"...", ".."}, StringSplitOptions.None);
Run Code Online (Sandbox Code Playgroud)
生成的数组元素是:
1. ""
2. ""
3. ""
Run Code Online (Sandbox Code Playgroud)
现在,如果你颠倒了分隔符的顺序,
"......".Split(new String[]{"..", "..."}, StringSplitOptions.None);
Run Code Online (Sandbox Code Playgroud)
生成的数组元素是:
1. ""
2. ""
3. ""
4. ""
Run Code Online (Sandbox Code Playgroud)
从这两个例子中,我倾向于得出结论,当从左到右遍历数组的每个元素时,Split方法递归地标记化.
但是,一旦我们将包含字母数字字符的分隔符放入等式中,很明显上述理论是错误的.
"5.x.7".Split(new String[]{".x", "x."}, StringSplitOptions.None)
Run Code Online (Sandbox Code Playgroud)
结果是: 1. "5" 2. ".7"
"5.x.7".Split(new String[]{"x.", ".x"}, StringSplitOptions.None)
Run Code Online (Sandbox Code Playgroud)
结果是: 1. "5" 2. ".7"
这次我们获得相同的输出,这意味着基于第一组示例理论化的规则不再适用.(即:如果始终根据数组中分隔符的位置确定分隔符优先级,那么在最后一个示例中,我们将获得"5."
&"7"
而不是"5"
&".7"
.
至于为什么我浪费时间去猜测.NET标准API是如何工作的,这是因为我想为我的java应用程序实现类似的功能,但是StringTokenizer和org.apache.commons.lang.StringUtils都没有提供拆分的能力.使用多个多字符分隔符的字符串(即使我要找到提供此功能的API,也很难知道它是否始终使用String.Split方法使用的相同算法进行标记.