Странно, похоже, что-то вроде ошибки в .NET (C #?) С маршалингом аргумента в рабочий поток.
Если вы реализуете IConvertable в переданной структуре:
struct MyPair<TKey, TValue> : IConvertable
{
public readonly TKey Key;
public readonly TValue Value;
public MyPair(TKey key, TValue value)
{
Key = key;
Value = value;
}
// I just used the smart-tag on IConvertable to get all these...
// public X ToX(IFormatProvider provider) { throw new InvalidCastException(); }
...
public object ToType(Type conversionType, IFormatProvider provider)
{
if (typeof(MyPair<TKey, TValue>).GUID == conversionType.GUID)
return this;
throw new InvalidCastException();
}
}
Работает нормально. Переданный параметр translationType не передает .Equal (), IsAssignableFrom () или что-либо еще, что я пробовал, кроме сравнения GUID, что, вероятно, связано с тем, почему он сначала запрашивает IConvertable.
РЕДАКТИРОВАТЬ: простой обходной путь заключается в использовании замыкания для передачи параметра:
var data = new Dictionary<string, string> {
{ "Hello", "World" },
{ "How are", "You?" },
{ "Goodbye", "World!" }
};
foreach (var pair in data)
{
var copy = pair; // define a different variable for each worker
Action worker = () => Console.WriteLine("Item {0}, {1}", copy.Key, copy.Value);
worker.BeginInvoke(null, null);
}
Конечно, если вам нужны результаты, вам необходимо сохранить IAsyncResults, которые, вероятно, будут иметь ту же проблему, что и параметры, в другом направлении. В качестве альтернативы вы можете добавить их в коллекцию, когда они будут завершены, но блокировка становится немного странной:
var data = new Dictionary<string, string> {
{ "Hello", "World" },
{ "How are", "You?" },
{ "Goodbye", "World!" }
};
var results = new List<KeyValuePair<string, string>>();
var pending = 0;
var done = new ManualResetEvent(false);
var workers = new List<Action>();
foreach (var pair in data)
{
++pending;
var copy = pair; // define a different variable for each worker
workers.Add(delegate()
{
Console.WriteLine("Item {0}, {1}", copy.Key, copy.Value);
lock (results)
results.Add(new KeyValuePair<string, string>("New " + copy.Key, "New " + copy.Value));
if (0 == Interlocked.Decrement(ref pending))
done.Set();
});
}
foreach (var worker in workers)
worker.BeginInvoke(null, null);
done.WaitOne();
foreach (var pair in results)
Console.WriteLine("Result {0}, {1}", pair.Key, pair.Value);