API KiteWorks с использованием HttpWebRequest и MultipartFormDataContent - PullRequest
0 голосов
/ 18 февраля 2020
jsonWebClient.DataContent = new System.Net.Http.MultipartFormDataContent();
ByteArrayContent bytes = new ByteArrayContent(File.ReadAllBytes(data.LocalFile));
bytes.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
jsonWebClient.DataContent.Add(bytes, "file", data.FileName);
jsonWebClient.DataContent.Add(bytes, "name", data.FileName);
jsonWebClient.DataContent.Add(new StringContent($"{Connection.UserId}"), "userId");
jsonWebClient.DataContent.Add(new StringContent($"{data.ParentId}"), "parentId");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.CreationTime}"), "created");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.LastWriteTime}"), "modified");
jsonWebClient.DataContent.Add(new StringContent($"{DateTime.Now}"), "clientCreated");
jsonWebClient.DataContent.Add(new StringContent($"{DateTime.Now}"), "clientModified");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.Length}"), "size");

Поэтому я пытаюсь сгенерировать MultipartFormDataContent для преобразования в байтовый массив или поток. Когда я делаю поток:

Stream stream = _dataContent.ReadAsStreamAsync().Result;

Я получаю исключение нехватки памяти.

Когда я пытаюсь сделать:

byte[] bytes = _dataContent.ReadAsByteArrayAsync().Result;

или

byte[] bytes = _dataContent.ReadAsByteArrayAsync().GetAwaiter().GetResult();

Он просто сидит там вечно и ничего не делает. Что я могу сделать, чтобы преобразовать его в правильный байтовый массив?

1 Ответ

0 голосов
/ 19 февраля 2020

Исходный источник [Как мне запустить асин c Метод задачи синхронно?] [Рейчел] Как мне запустить асин c Задача метод синхронно? Метод синхронно

public static class AsyncHelpers
{
   /// <summary>
   /// Execute's an async Task<T> method which has a void return value synchronously
   /// </summary>
   /// <param name="task">Task<T> method to execute</param>
   public static void RunSync(Func<Task> task)
   {
      var oldContext = SynchronizationContext.Current;
      var synch = new ExclusiveSynchronizationContext();
      SynchronizationContext.SetSynchronizationContext(synch);
      synch.Post(async _ =>
      {
          try
          {
              await task();
          }
          catch (Exception e)
          {
              synch.InnerException = e;
              throw;
          }
          finally
          {
              synch.EndMessageLoop();
          }
       }, null);
      synch.BeginMessageLoop();

      SynchronizationContext.SetSynchronizationContext(oldContext);
  }

  /// <summary>
  /// Execute's an async Task<T> method which has a T return type synchronously
  /// </summary>
  /// <typeparam name="T">Return Type</typeparam>
  /// <param name="task">Task<T> method to execute</param>
  /// <returns></returns>
  public static T RunSync<T>(Func<Task<T>> task)
  {
     var oldContext = SynchronizationContext.Current;
     var synch = new ExclusiveSynchronizationContext();
     SynchronizationContext.SetSynchronizationContext(synch);
     T ret = default(T);
     synch.Post(async _ =>
     {
         try
         {
             ret = await task();
         }
         catch (Exception e)
         {
             synch.InnerException = e;
             throw;
         }
         finally
         {
             synch.EndMessageLoop();
         }
     }, null);
     synch.BeginMessageLoop();
     SynchronizationContext.SetSynchronizationContext(oldContext);
     return ret;
 }

 private class ExclusiveSynchronizationContext : SynchronizationContext
 {
    private bool done;
    public Exception InnerException { get; set; }
    readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false);
    readonly Queue<Tuple<SendOrPostCallback, object>> items =
        new Queue<Tuple<SendOrPostCallback, object>>();

    public override void Send(SendOrPostCallback d, object state)
    {
        throw new NotSupportedException("We cannot send to our same thread");
    }

    public override void Post(SendOrPostCallback d, object state)
    {
        lock (items)
        {
            items.Enqueue(Tuple.Create(d, state));
        }
        workItemsWaiting.Set();
    }

    public void EndMessageLoop()
    {
        Post(_ => done = true, null);
    }

    public void BeginMessageLoop()
    {
        while (!done)
        {
            Tuple<SendOrPostCallback, object> task = null;
            lock (items)
            {
                if (items.Count > 0)
                {
                    task = items.Dequeue();
                }
            }
            if (task != null)
            {
                task.Item1(task.Item2);
                if (InnerException != null) // the method threw an exeption
                {
                    throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException);
                }
            }
            else
            {
                workItemsWaiting.WaitOne();
            }
        }
    }

    public override SynchronizationContext CreateCopy()
    {
        return this;
    }
  }
}

С этим классом я смог преобразовать его сразу же, не дожидаясь, и не было проблем с исключением из нехватки памяти.

...