Локальный путь к файлу не "file: //". Вы можете обычно читать файл, используя локальный путь к файлу как
var path = "C:\\...";
, а затем отправлять содержимое в браузер клиента.
Если файл находится не на локальном компьютере, доступ к нему возможен только через сетевой ресурс. Затем вы можете использовать UNC-пути, например
var path = @"\\Server\Path\...";
Если Вы будете подозревать, что у Вас есть проблемы параллелизма при доступе к словарю затем то фиксация не будет иметь применения. Это решит определенную проблему, которую Вы испытываете, однако если у Вас есть параллельный доступ к словарю, Вы собираетесь иметь больше проблем в будущем.
Рассмотрите блокировку доступа к словарю при изменении его.
использование примера ng5000, измененного к предложенной стратегии блокировки, дало бы нам:
public static class ThreadSafeDictionary
{
private static readonly Dictionary<string, int> dict = new Dictionary<string, int>();
public static void AddItem(string key, int value)
{
lock (((IDictionary)dict).SyncRoot)
{
if (!dict.ContainsKey(key))
dict.Add(key, value);
}
}
}
наслаждаться...
jimi
Править: обратите внимание, что класс должен быть статичным для понимания этого примера!! ;)
Первый код (предполагающий, что типом Словаря является Система. Наборы. Универсальный. Словарь), не скомпилирует. Нет никакой общественности, содержит (ни Содержит метод).
Тем не менее существует возможность, что у Вас могла быть проблема параллелизма. Поскольку Вы подразумевали, что другой поток мог изменить словарь после проверки ContainsKey и перед вставкой. Для исправления этого, оператор блокировки является способом пойти.
Одна точка - я предпочел бы видеть словарь, перенесенный в ориентированный на многопотоковое исполнение класс, что-то как (протесты: не завершенный, и не предназначенный как код ссылки, и может быть улучшен):
public class ThreadSafeDictionary
{
private Dictionary<string, int> dict = new Dictionary<string, int>();
private object padlock = new object();
public void AddItem( string key, int value )
{
lock ( padlock )
{
if( !dict.ContainsKey( key ) )
dict.Add( key, value );
}
}
}
То, как реализовать ориентированные на многопотоковое исполнение словари, было покрыто полностью здесь.
Поскольку Megacan сказал, что Вы могли бы хотеть сфокусироваться на решении любых возможных проблем параллелизма, которые Вы могли бы иметь в своем решении.
Я рекомендую использовать SynchronizedKeyedCollection, хотя это могло бы быть далеко многим факторинг ре для Вас, так как участники для класса не являются тем же те словаря.
Трудный сказать, является ли это действительно проблемой параллелизма. Если к словарю получают доступ несколько потоков, то это может действительно быть проблема параллелизма, но я думаю, что необходимо добавить некоторый код трассировки для обнаружения, кто преступник.
Если к словарю получают доступ несколько потоков, то необходимо действительно удостовериться, что Содержание (или ContainsKey) и Добавляет, что методы называют в одной атомарной транзакции. Чтобы сделать это, необходимо действительно назвать эти 2 метода в блокировке.
lock( dict.SyncRoot )
{
if( dict.Contains( .. ) == false )
dict.Add ( );
}
lock (((IDictionary)dict).SyncRoot)
{
if(!dict.Contains( .. ))
dict.Add ( );
}
это работает на меня (см. обновление ng5000 пример ниже), :)
Существует ориентированный на многопотоковое исполнение класс словаря, встроенный в Платформу.NET, которая уже предлагает хорошее начало для решения Вашей проблемы, которая могла действительно быть связанным параллелизмом.
Это - абстрактный класс под названием SynchronizedKeyedCollection (K, T), что Вы могли произойти из и добавить метод, который содержит вызов к, Содержит, затем Добавляют в блокировке, которая соединяет основу. SyncRoot.
Туз - странный, что это не работало над Вашим кодом, это, конечно, делает согласно примеру (я знаю, что это не помогает Вам, просто любопытство действительно!!).
Надежда Вы разрабатываете его, я уверен, что это будет довольно простая причина сбоя. Вы могли бы даже хотеть попробовать пример вместо своего кода, чтобы видеть, является ли это некоторая другая проблема.
Не был должен
if (!evilDict.contains(item.name.ToLower().Trim()))
быть
if (!evilDict.ContainsKey(item.name.ToLower().Trim()))
?
Туз,
Создайте новый WindowsFormsApplication (.Net 2.0) и вставьте код в код Form1.cs. (Вам, вероятно, придется изменить имя пространства имен от WindowsFormsApplication1 до что Ваши системные значения по умолчанию к). Кроме того, добавьте кнопку к форме. Так или иначе здесь все это:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private readonly Dictionary<string, int> localDict1 = new Dictionary<string, int>();
private readonly Dictionary<string, string> localDict2 = new Dictionary<string, string>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// use two different dictionaries just to show it working with
// different data types (i.e. we could use class objects too)
if (localDict1 != null)
{
ThreadSafeDictionaryStatic.AddItem(localDict1, "New Item :1", 1);
ThreadSafeDictionaryStatic.AddItem(localDict1, "New Item :2", 2);
}
if (localDict2 != null)
ThreadSafeDictionaryStatic.AddItem(localDict2, "New Item :1", "this is not a number");
}
}
public static class ThreadSafeDictionaryStatic
{
public static void AddItem<T>(IDictionary<string, T> dict, string key, T value)
{
if (dict == null) return;
lock (((IDictionary)dict).SyncRoot)
{
if (!dict.ContainsKey(key))
dict.Add(key, value);
else
{
// awful and we'd never ever show a message box in real life - however!!
var result = dict[key];
MessageBox.Show(String.Format("Key '{0}' is already present with a value of '{1}'", key, result));
}
}
}
public static T GetItem<T>(IDictionary<string, T> dict, string key)
{
if (dict == null) return default(T);
if (dict.ContainsKey(key))
return dict[key];
else
return default(T);
}
public static bool Remove<T>(IDictionary<string, T> dict, string key)
{
if (dict == null) return false;
lock (((IDictionary)dict).SyncRoot)
{
if (dict.ContainsKey(key))
return dict.Remove(key);
}
return false;
}
}
}
Сообщите мне, как это идет...
Править: восстановил класс для соответствия сигнатуре метода, также используемые дженерики, поскольку Вы захотите, чтобы метод принял ЛЮБОЙ вид объекта. можно легко возвратить его путем удаления <T>
судьи и т.д.