最近开发一个多线程上传的Web系统,通过网页将文件多线程上传到服务器。下面是主程序部分代码:
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
fs.Position = 0;
UploadThread thd = null;  //文件上传的子线程的对象
ManualResetEvent[] events = new ManualResetEvent[threadCount];
for (int i = 0; i < threadCount; i++)
{
events[i] = new ManualResetEvent(false);
realSize = ((fileSize - i * bufferSize) > bufferSize) ? bufferSize : (int)(fileSize - i * bufferSize);
if (realSize < bufferSize)
{
byte[] dataOdd = new byte[realSize];
fs.Read(dataOdd, 0, realSize);
thd = new UploadThread(fileName, readedSize, dataOdd);  //文件上传的子线程的实例
readedSize += realSize;
}
else
{
fs.Read(dataTemp, 0, bufferSize);
thd = new UploadThread(fileName, readedSize, dataTemp);
readedSize += bufferSize;
}
ThreadPool.QueueUserWorkItem(new WaitCallback(thd.UploadFile), events[i]);  // 将子线程加入线程队列
Thread.Sleep(1000);  //主线程休眠1000毫秒!!!!!!!!!!!!!问题重点!!!!!!!!!!!!!
}
WaitHandle.WaitAll(events);
自线程中写文件方式:
fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
fs.Position = startPosition;
fs.Write(ByteData, 0, size);
fs.Flush();
问题一:
上面标注的“问题重点”处,如果不强制主线程休眠的话,就会出现有些线程抢占其他线程的时间片,重复执行多次,而有些线程根本得不到执行的情况;我想知道本来线程们都已进入排队队列中了为什么还会出现这种情况,除了强制主线程休眠外还有没有其他办法?因为目前这样做上传过程中仍然会丢数据。问题二:
目前采用FileStream的文件读写方式,位置参数只能是int型,如果大文件的话就会有问题;有没有更好的方式?

解决方案 »

  1.   

    现在的意思就是说不想用休眠,为什么不能让ThreadPool中的线程一个执行一次?
      

  2.   

    join用在这里的话貌似会失去多线程的意义了吧?
      

  3.   

    不对,因该是
    Application.DoEvents();
      

  4.   

    楼上的可能没看清楚,我现在用的是ThreadPool来管理线程的。
    关于ThreadPool的资料都不是很详细,不过根据资料上说的ThreadPool中的线程应该是队列一样的,一个执行完了在执行另一个,不应该会有抢占的情况的啊。可为什么还会出现线程重复执行的情况呢?
      

  5.   

    不过根据资料上说的ThreadPool中的线程应该是队列一样的,一个执行完了在执行另一个,不应该会有抢占的情况的啊。
    -----------------------------
    什么资料?有这样解释ThreadPool的啊?!
      

  6.   

    线程调度一般是发生IO的线程容易被挂起,而最近的线程可能会被最快切换回来,因为这样可能开销最小,
    所以没有主thread的sleep,很可能最早创建的线程在fs.write时被晾在一边,直到很后面才恢复,而后创建的线程反倒一直得到运行其它的一些想法byte[] dataOdd = new byte[realSize];建议改成
    byte[,] dataOdd;
    for 循环之前
    dataOdd = new byte[threadCount, bufferSize];for循环中改
    fs.Read(dataOdd[i], 0, realSize);
    thd = new UploadThread(fileName, readedSize, dataOdd[i]);  语法上可能有点问题,反正意思是缓冲区分离另外,msdn上waitall是使用WaitHandle.WaitAll(new WaitHandle[]{mre1, mre2, mre3});
    使用WaitHandle数组,不知道有没有关系
      

  7.   

    我认为int型表示文件长度足够了,如果比int型表示的最大长度还长的文件,你是无法处理的!