Ja, unter bestimmten Bedingungen, wie aus dem Beispielcode ersichtlich.
public static class ConsoleApp {
public static void Main() {
Console.WriteLine("Write something.");
var str = Console.ReadLine();
if (String.IsNullOrEmpty(str))
return;
new Thread(() => TestMethod(null, str, "")).Start();
// Allow TestMethod to execute.
Thread.Sleep(100);
unsafe {
// Grab pointer to our string.
var gcHandle = GCHandle.Alloc(str, GCHandleType.Pinned);
var strPtr = (char*)gcHandle.AddrOfPinnedObject().ToPointer();
// Change it, one character at a time, wait a little more than
// TestMethod for dramatic effect.
for (int i = 0; i < str.Length; ++i) {
strPtr[i] = 'x';
Thread.Sleep(1100);
}
}
// Tell TestMethod to quit.
_done = true;
Console.WriteLine("Done.");
Console.ReadLine();
}
private static Boolean _done;
public static void TestMethod(String x, String y, String z) {
x = y + z;
while (!_done) {
Console.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), x);
Thread.Sleep(1000);
}
}
}
Anforderungen (afaik)
- Unsafe Kontext Zeiger zu verwenden.
- Verwenden Sie String.Concat (String str0, String str1), das für Fälle optimiert ist, in denen
str0 == String.Empty
oder str1 == String.Empty
die nicht leere Zeichenfolge zurückgibt. Das Verketten von drei oder mehr Zeichenfolgen würde eine neue Zeichenfolge erzeugen, die dies blockiert.
Hier ist eine feste Version der eine modifizierte.
public static class ConsoleApp {
private static Int32 _counter = 10;
public static void Main() {
for (var i = 0; i < 10; i++) {
var str = GetString();
Console.WriteLine("Input: {0} - {1}", DateTime.Now.ToLongTimeString(), str);
new Thread(() => TestMethod(str)).Start();
unsafe {
var gcHandle = GCHandle.Alloc(str, GCHandleType.Pinned);
var strPtr = (char*)gcHandle.AddrOfPinnedObject().ToPointer();
strPtr[0] = 'A';
strPtr[1] = 'B';
strPtr[2] = 'C';
strPtr[3] = 'D';
strPtr[4] = 'E';
}
}
Console.WriteLine("Done.");
Console.ReadLine();
}
private static String GetString() {
var builder = new StringBuilder();
for (var i = _counter; i < _counter + 10; i++)
builder.Append(i.ToString());
_counter = _counter + 10;
return builder.ToString();
}
public static void TestMethod(Object y) {
Thread.Sleep(2000);
Console.WriteLine("Output: {0} {1}", DateTime.Now.ToLongTimeString(), y);
}
}
noch Das funktioniert, weil Object.ToString() in String außer Kraft gesetzt wird diese zurück, so dass genau die gleiche Referenz zurück.
Danke. Parameter sind lokale Variablen und unabhängig von anderen Threads. Aber gibt es eine einfache Möglichkeit, solche Probleme neu zu erstellen/zu debuggen? – humblelistener
@Pkay: Normalerweise nicht, fürchte ich. Threading-Bugs sind schwierig zu finden und zu testen :( –