相关疑难解决方法(0)

在.NET中创建阻塞队列<T>?

我有一个场景,我有多个线程添加到队列和多个线程从同一队列读取.如果队列达到特定大小,则填充队列的所有线程将在添加时被阻止,直到从队列中删除项目为止.

下面的解决方案就是我现在正在使用的问题,我的问题是:如何改进?是否有一个对象已经在我应该使用的BCL中启用此行为?

internal class BlockingCollection<T> : CollectionBase, IEnumerable
{
    //todo: might be worth changing this into a proper QUEUE

    private AutoResetEvent _FullEvent = new AutoResetEvent(false);

    internal T this[int i]
    {
        get { return (T) List[i]; }
    }

    private int _MaxSize;
    internal int MaxSize
    {
        get { return _MaxSize; }
        set
        {
            _MaxSize = value;
            checkSize();
        }
    }

    internal BlockingCollection(int maxSize)
    {
        MaxSize = maxSize;
    }

    internal void Add(T item)
    {
        Trace.WriteLine(string.Format("BlockingCollection add waiting: {0}", Thread.CurrentThread.ManagedThreadId));

        _FullEvent.WaitOne();

        List.Add(item);

        Trace.WriteLine(string.Format("BlockingCollection …
Run Code Online (Sandbox Code Playgroud)

.net c# queue collections multithreading

161
推荐指数
6
解决办法
10万
查看次数

使用相同的SqlConnection对SqlCommand.BeginExecuteNonQuery进行多个并发调用

我有一些使用SqlConnection创建临时表(例如#Foo)的C#代码,调用存储过程来填充那些临时表并将结果返回给C#客户端,使用c#对这些结果执行复杂计算,并使用计算结果更新之前创建的临时表之一.

由于整个过程中使用的临时表,我们必须只有一个SqlConnection.

我发现了使用计算结果更新临时表时的性能瓶颈.此代码已经对更新进行批处理,以防止C#客户端内存不足.每批计算数据通过SqlCommand.ExecuteNonQuery发送到存储过程,然后sproc会更新临时表.代码将大部分时间花在对ExecuteNonQuery的调用上.

因此,我将其更改为BeginExecuteNonQuery,以及在线程上等待并调用EndExecuteNonQuery的代码.这提高了性能约三分之一,但我担心使用相同的SqlConnection对SqlCommand.BeginExecuteNonQuery进行多次并发调用.

这样可以,还是会遇到线程问题?

很抱歉很长的解释.

MSDN文档声明:

BeginExecuteNonQuery方法立即返回,但在代码执行相应的EndExecuteNonQuery方法调用之前,它不能执行任何其他对同一SqlCommand对象启动同步或异步执行的调用.

这似乎意味着不同的SqlCommand对象可以在第一个SqlCommand完成之前调用BeginExecuteNonQuery.

以下是一些说明问题的代码:

    private class SqlCommandData
    {
        public SqlCommand Command { get; set; }
        public IAsyncResult AsyncResult { get; set; }
    }

    public static void TestMultipleConcurrentBeginExecuteNonQueryCalls(string baseConnectionString)
    {
        var connectionStringBuilder = new SqlConnectionStringBuilder(baseConnectionString)
                                          {
                                              MultipleActiveResultSets = true,
                                              AsynchronousProcessing = true
                                          };
        using (var connection = new SqlConnection(connectionStringBuilder.ConnectionString))
        {
            connection.Open();

            // ELIDED - code that uses connection to do various Sql work

            SqlDataReader dataReader = null;
                // in real code, this would be initialized …
Run Code Online (Sandbox Code Playgroud)

c# sql-server ado.net multithreading

28
推荐指数
2
解决办法
1万
查看次数

如何使用ConcurrentQueue <T>进行线程处理

我想弄清楚使用队列的最佳方法是什么.我有一个返回DataTable的进程.反过来,每个DataTable都与之前的DataTable合并.有一个问题,在最终的BulkCopy(OutOfMemory)之前要保留的记录太多.

所以,我已经确定我应该立即处理每个传入的DataTable.考虑一下ConcurrentQueue<T>......但我不知道该WriteQueuedData()方法如何知道将一个表出列并将其写入数据库.

例如:

public class TableTransporter
{
    private ConcurrentQueue<DataTable> tableQueue = new ConcurrentQueue<DataTable>();

    public TableTransporter()
    {
        tableQueue.OnItemQueued += new EventHandler(WriteQueuedData);   // no events available
    }

    public void ExtractData()
    {
        DataTable table;

        // perform data extraction
        tableQueue.Enqueue(table);
    }

    private void WriteQueuedData(object sender, EventArgs e)
    {
        BulkCopy(e.Table);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是,除了我实际上没有订阅任何事件的事实,如果我ExtractData()异步调用这将是我需要的全部内容吗?第二,我是否缺少关于ConcurrentQueue<T>函数的方式以及需要某种形式的触发器与排队对象异步工作的东西?

更新 我刚刚派生出一个ConcurrentQueue<T>具有OnItemQueued事件处理程序的类.然后:

new public void Enqueue (DataTable Table)
{
    base.Enqueue(Table);
    OnTableQueued(new TableQueuedEventArgs(Table));
}

public void OnTableQueued(TableQueuedEventArgs table)
{
    EventHandler<TableQueuedEventArgs> handler = TableQueued; …
Run Code Online (Sandbox Code Playgroud)

c# queue multithreading concurrent-collections

18
推荐指数
2
解决办法
5万
查看次数

部分线程安全的字典

我有一个类维护一个Dictionary缓存一些数据的私有实例.

该类使用a从多个线程写入字典ReaderWriterLockSlim.

我想在课外公开字典的值.
什么是线程安全的方法呢?

现在,我有以下内容:

public ReadOnlyCollection<MyClass> Values() {
    using (sync.ReadLock())
        return new ReadOnlyCollection<MyClass>(cache.Values.ToArray()); 
}
Run Code Online (Sandbox Code Playgroud)

有没有办法这样做而不需要多次复制集合?

我正在使用.Net 3.5(不是4.0)

.net c# thread-safety

3
推荐指数
1
解决办法
1099
查看次数

在c#中排队执行线程

我有异步执行作业,每隔几分钟,有时Windows服务执行和以前的工作还没有完成一个窗口服务,使用线程有排队的新的工作方式,如果前一个处理不当完成,以便它开始运行时第一份工作完成了吗?

.net c# multithreading

2
推荐指数
1
解决办法
635
查看次数